Documentation ¶
Overview ¶
Package fields provides a view of the fields of a struct that follows the Go rules, amended to consider tags and case insensitivity.
Usage ¶
First define a function that interprets tags:
func parseTag(st reflect.StructTag) (name string, keep bool, other interface{}, err error) { ... }
The function's return values describe whether to ignore the field completely or provide an alternate name, as well as other data from the parse that is stored to avoid re-parsing.
Then define a function to validate the type:
func validate(t reflect.Type) error { ... }
Then, if necessary, define a function to specify leaf types - types which should be considered one field and not be recursed into:
func isLeafType(t reflect.Type) bool { ... }
eg:
func isLeafType(t reflect.Type) bool { return t == reflect.TypeOf(time.Time{}) }
Next, construct a Cache, passing your functions. As its name suggests, a Cache remembers validation and field information for a type, so subsequent calls with the same type are very fast.
cache := fields.NewCache(parseTag, validate, isLeafType)
To get the fields of a struct type as determined by the above rules, call the Fields method:
fields, err := cache.Fields(reflect.TypeOf(MyStruct{}))
The return value can be treated as a slice of Fields.
Given a string, such as a key or column name obtained during unmarshalling, call Match on the list of fields to find a field whose name is the best match:
field := fields.Match(name)
Match looks for an exact match first, then falls back to a case-insensitive comparison.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ParseStandardTag ¶
func ParseStandardTag(key string, t reflect.StructTag) (name string, keep bool, options []string, err error)
ParseStandardTag extracts the sub-tag named by key, then parses it using the de facto standard format introduced in encoding/json:
"-" means "ignore this tag". It must occur by itself. (parseStandardTag returns an error in this case, whereas encoding/json accepts the "-" even if it is not alone.) "<name>" provides an alternative name for the field "<name>,opt1,opt2,..." specifies options after the name.
The options are returned as a []string.
Types ¶
type Cache ¶
type Cache struct {
// contains filtered or unexported fields
}
A Cache records information about the fields of struct types.
A Cache is safe for use by multiple goroutines.
func NewCache ¶
func NewCache(parseTag ParseTagFunc, validate ValidateFunc, leafTypes LeafTypesFunc) *Cache
NewCache constructs a Cache.
Its first argument should be a function that accepts a struct tag and returns four values: an alternative name for the field extracted from the tag, a boolean saying whether to keep the field or ignore it, additional data that is stored with the field information to avoid having to parse the tag again, and an error.
Its second argument should be a function that accepts a reflect.Type and returns an error if the struct type is invalid in any way. For example, it may check that all of the struct field tags are valid, or that all fields are of an appropriate type.
func (*Cache) Fields ¶
Fields returns all the exported fields of t, which must be a struct type. It follows the standard Go rules for embedded fields, modified by the presence of tags. The result is sorted lexicographically by index.
These rules apply in the absence of tags: Anonymous struct fields are treated as if their inner exported fields were fields in the outer struct (embedding). The result includes all fields that aren't shadowed by fields at higher level of embedding. If more than one field with the same name exists at the same level of embedding, it is excluded. An anonymous field that is not of struct type is treated as having its type as its name.
Tags modify these rules as follows: A field's tag is used as its name. An anonymous struct field with a name given in its tag is treated as a field having that name, rather than an embedded struct (the struct's fields will not be returned). If more than one field with the same name exists at the same level of embedding, but exactly one of them is tagged, then the tagged field is reported and the others are ignored.
type Field ¶
type Field struct { Name string // effective field name NameFromTag bool // did Name come from a tag? Type reflect.Type // field type Index []int // index sequence, for reflect.Value.FieldByIndex ParsedTag interface{} // third return value of the parseTag function // contains filtered or unexported fields }
A Field records information about a struct field.
type LeafTypesFunc ¶
LeafTypesFunc is a function that accepts a reflect.Type and returns true if the struct type a leaf, or false if not. TODO(deklerk): is this description accurate?
type List ¶
type List []Field
A List is a list of Fields.
func (List) Match ¶
Match returns the field in the list whose name best matches the supplied name, nor nil if no field does. If there is a field with the exact name, it is returned. Otherwise the first field (sorted by index) whose name matches case-insensitively is returned.
func (List) MatchBytes ¶
MatchBytes is identical to Match, except that the argument is a byte slice.
type ParseTagFunc ¶
ParseTagFunc is a function that accepts a struct tag and returns four values: an alternative name for the field extracted from the tag, a boolean saying whether to keep the field or ignore it, additional data that is stored with the field information to avoid having to parse the tag again, and an error.
type ValidateFunc ¶
ValidateFunc is a function that accepts a reflect.Type and returns an error if the struct type is invalid in any way.