summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/gorilla/schema/cache.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/gorilla/schema/cache.go')
-rw-r--r--vendor/github.com/gorilla/schema/cache.go63
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
}