web icon indicating copy to clipboard operation
web copied to clipboard

Use struct tags match Params when using `UnmarshalParams`

Open stevvooe opened this issue 14 years ago • 0 comments

To deal with the naming constraints of a struct, the json module allows one too specify tags to guide unmarshaling/marshaling:

type MyParams struct {
    FooBar string "foo_bar"
}

This would serialize the contents of FooBar with the key "foo_bar" and deserialize such that an item with the "foo_bar" will be placed into FooBar.

I added this modification to allow web.go use these tags to guide parameter unmarshaling in the same manner:

diff --git a/request.go b/request.go
index 0e2fc4c..9df8837 100644
--- a/request.go
+++ b/request.go
@@ -328,17 +328,33 @@ func (r *Request) writeToContainer(val reflect.Value) os.Error {
             v.SetElem(mk, mv)
         }
     case *reflect.StructValue:
+        // A little preprocessing to make this faster
+        tagMap := map[string](reflect.Value) {}
+        nameMap := map[string](reflect.Value) {}
+
+        ty := v.Type().(*reflect.StructType)
+        for i := v.NumField(); i >= 0; i-- {
+            field := ty.Field(i)
+            if len(field.Tag) > 0 {
+                tagMap[strings.ToLower(field.Tag)] = v.Field(i)
+            }
+
+            if len(field.Name) > 0 {
+                nameMap[strings.ToLower(field.Name)] = v.Field(i)
+            }
+        }
+
         for pk, pv := range r.Params {
-            //try case sensitive match
-            field := v.FieldByName(pk)
-            if field != nil {
+            // try struct tag matching first
+            if field, ok := tagMap[strings.ToLower(pk)]; ok {
                 writeTo(pv, field)
+                continue
             }

-            //try case insensitive matching
-            field = v.FieldByNameFunc(func(s string) bool { return matchName(pk, s) })
-            if field != nil {
+            // now try case-insensitive
+            if field, ok := nameMap[strings.ToLower(pk)]; ok {
                 writeTo(pv, field)
+                continue
             }

         }

stevvooe avatar Nov 28 '10 22:11 stevvooe