web
web copied to clipboard
Use struct tags match Params when using `UnmarshalParams`
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
}
}