Skip to content

muir/reflectutils

Repository files navigation

reflectutils - utility functions for working with Golang's reflect package

GoDoc unit tests report card codecov

Install:

go get github.com/muir/reflectutils

Reflectutils is simply a repository for functions useful for working with Golang's reflect package.

Here's the highlights:

Walking structures

func WalkStructElements(t reflect.Type, f func(reflect.StructField) bool)

Recursively walking a struct with reflect has a pitfalls:

  1. It isn't recurse with respect to embeded structs
  2. The Index field of reflect.Structfield of embedded structs is not relative to your starting point.

WalkStructElements() walks embedded elements and it updates StructField.Index so that it is relative to the root struct that was passed in.

Setting elements

func MakeStringSetter(t reflect.Type, optArgs ...StringSetterArg) (func(target reflect.Value, value string) error, error)

MakeStringSetter() returns a function that can be used to assing to reflect.Value given a string value. It can handle arrays and slices (splits strings on commas).

Parsing struct tags

Use SplitTag() to break a struct tag into it's elements and then use Tag.Fill() to parse it into a struct.

For example:

type TagInfo struct {
	Name	string	`pt:"0"`     // positional, first argument
	Train	bool	`pt:"train"` // boolean: true: "train", "train=true"; false: "!train", "train=false"
	Count	int	`pt:"count"` // integer value will be parsed
}

st := reflect.StructTag(`foo:"bar,!train,count=9"`)
var tagInfo TagInfo
err := GetTag(st, "foo").Fill(&tagInfo)

// tagInfo.Name will be "bar"
// tagInfo.Train will be false
// tagInfo.Count will be 9

Type names

The TypeName() function exists to disambiguate between type names that are versioned. reflect.Type.String() will hides package versions. This doesn't matter unless you've, unfortunately, imported multiple versions of the same package.

Development status

Reflectutils is used by several packages. Backwards compatability is expected.