fields

package
v0.22.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 9, 2018 License: Apache-2.0 Imports: 7 Imported by: 0

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 added in v0.17.0

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

func (c *Cache) Fields(t reflect.Type) (List, error)

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 added in v0.7.0

type LeafTypesFunc func(reflect.Type) bool

type List

type List []Field

A List is a list of Fields.

func (List) Match

func (l List) Match(name string) *Field

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

func (l List) MatchBytes(name []byte) *Field

MatchBytes is identical to Match, except that the argument is a byte slice.

type ParseTagFunc added in v0.6.0

type ParseTagFunc func(reflect.StructTag) (name string, keep bool, other interface{}, err error)

type ValidateFunc added in v0.6.0

type ValidateFunc func(reflect.Type) error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL