diff options
Diffstat (limited to 'vendor/github.com/gorilla/schema/cache.go')
-rw-r--r-- | vendor/github.com/gorilla/schema/cache.go | 63 |
1 files changed, 43 insertions, 20 deletions
diff --git a/vendor/github.com/gorilla/schema/cache.go b/vendor/github.com/gorilla/schema/cache.go index 1613b1e6..b2c5995d 100644 --- a/vendor/github.com/gorilla/schema/cache.go +++ b/vendor/github.com/gorilla/schema/cache.go @@ -138,7 +138,12 @@ func (c *cache) create(t reflect.Type, info *structInfo) *structInfo { ft = ft.Elem() } if ft.Kind() == reflect.Struct { + bef := len(info.fields) c.create(ft, info) + for _, fi := range info.fields[bef:len(info.fields)] { + // exclude required check because duplicated to embedded field + fi.required = false + } } } c.createField(field, info) @@ -148,7 +153,7 @@ func (c *cache) create(t reflect.Type, info *structInfo) *structInfo { // createField creates a fieldInfo for the given field. func (c *cache) createField(field reflect.StructField, info *structInfo) { - alias := fieldAlias(field, c.tag) + alias, options := fieldAlias(field, c.tag) if alias == "-" { // Ignore this field. return @@ -173,17 +178,19 @@ func (c *cache) createField(field reflect.StructField, info *structInfo) { } } if isStruct = ft.Kind() == reflect.Struct; !isStruct { - if conv := c.conv[ft.Kind()]; conv == nil { + if conv := c.converter(ft); conv == nil { // Type is not supported. return } } info.fields = append(info.fields, &fieldInfo{ - typ: field.Type, - name: field.Name, - ss: isSlice && isStruct, - alias: alias, + typ: field.Type, + name: field.Name, + ss: isSlice && isStruct, + alias: alias, + anon: field.Anonymous, + required: options.Contains("required"), }) } @@ -212,10 +219,12 @@ func (i *structInfo) get(alias string) *fieldInfo { } type fieldInfo struct { - typ reflect.Type - name string // field name in the struct. - ss bool // true if this is a slice of structs. - alias string + typ reflect.Type + name string // field name in the struct. + ss bool // true if this is a slice of structs. + alias string + anon bool // is an embedded field + required bool // tag option } type pathPart struct { @@ -227,19 +236,33 @@ type pathPart struct { // ---------------------------------------------------------------------------- // fieldAlias parses a field tag to get a field alias. -func fieldAlias(field reflect.StructField, tagName string) string { - var alias string +func fieldAlias(field reflect.StructField, tagName string) (alias string, options tagOptions) { if tag := field.Tag.Get(tagName); tag != "" { - // For now tags only support the name but let's follow the - // comma convention from encoding/json and others. - if idx := strings.Index(tag, ","); idx == -1 { - alias = tag - } else { - alias = tag[:idx] - } + alias, options = parseTag(tag) } if alias == "" { alias = field.Name } - return alias + return alias, options +} + +// tagOptions is the string following a comma in a struct field's tag, or +// the empty string. It does not include the leading comma. +type tagOptions []string + +// parseTag splits a struct field's url tag into its name and comma-separated +// options. +func parseTag(tag string) (string, tagOptions) { + s := strings.Split(tag, ",") + return s[0], s[1:] +} + +// Contains checks whether the tagOptions contains the specified option. +func (o tagOptions) Contains(option string) bool { + for _, s := range o { + if s == option { + return true + } + } + return false } |