structure: add omitnested support to Fields
This commit is contained in:
parent
eacf1a7590
commit
72596462dd
59
structure.go
59
structure.go
@ -88,6 +88,37 @@ func Values(s interface{}) []interface{} {
|
||||
|
||||
}
|
||||
|
||||
// Fields returns a slice of field names. A struct tag with the content of "-"
|
||||
// ignores the checking of that particular field. Example:
|
||||
//
|
||||
// // Field is ignored by this package.
|
||||
// Field bool `structure:"-"`
|
||||
//
|
||||
// Note that only exported fields of a struct can be accessed, non exported
|
||||
// fields will be neglected. It panics if s's kind is not struct.
|
||||
func Fields(s interface{}) []string {
|
||||
v, fields := strctInfo(s)
|
||||
|
||||
keys := make([]string, 0)
|
||||
for _, field := range fields {
|
||||
val := v.FieldByName(field.Name)
|
||||
|
||||
_, tagOpts := parseTag(field.Tag.Get(DefaultTagName))
|
||||
|
||||
if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") {
|
||||
// look out for embedded structs, and convert them to a
|
||||
// []string to be added to the final values slice
|
||||
for _, embeddedVal := range Fields(val.Interface()) {
|
||||
keys = append(keys, embeddedVal)
|
||||
}
|
||||
}
|
||||
|
||||
keys = append(keys, field.Name)
|
||||
}
|
||||
|
||||
return keys
|
||||
}
|
||||
|
||||
// IsZero returns true if all fields in a struct is a zero value (not
|
||||
// initialized) A struct tag with the content of "-" ignores the checking of
|
||||
// that particular field. Example:
|
||||
@ -163,34 +194,6 @@ func HasZero(s interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Fields returns a slice of field names. A struct tag with the content of "-"
|
||||
// ignores the checking of that particular field. Example:
|
||||
//
|
||||
// // Field is ignored by this package.
|
||||
// Field bool `structure:"-"`
|
||||
//
|
||||
// Note that only exported fields of a struct can be accessed, non exported
|
||||
// fields will be neglected. It panics if s's kind is not struct.
|
||||
func Fields(s interface{}) []string {
|
||||
v, fields := strctInfo(s)
|
||||
|
||||
keys := make([]string, 0)
|
||||
for _, field := range fields {
|
||||
val := v.FieldByName(field.Name)
|
||||
if IsStruct(val.Interface()) {
|
||||
// look out for embedded structs, and convert them to a
|
||||
// []string to be added to the final values slice
|
||||
for _, embeddedVal := range Fields(val.Interface()) {
|
||||
keys = append(keys, embeddedVal)
|
||||
}
|
||||
}
|
||||
|
||||
keys = append(keys, field.Name)
|
||||
}
|
||||
|
||||
return keys
|
||||
}
|
||||
|
||||
// IsStruct returns true if the given variable is a struct or a pointer to
|
||||
// struct.
|
||||
func IsStruct(s interface{}) bool {
|
||||
|
||||
@ -411,6 +411,43 @@ func TestFields(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFields_OmitNested(t *testing.T) {
|
||||
type A struct {
|
||||
Name string
|
||||
Value string
|
||||
Number int
|
||||
Enabled bool
|
||||
}
|
||||
a := A{Name: "example"}
|
||||
|
||||
type B struct {
|
||||
A A `structure:",omitnested"`
|
||||
C int
|
||||
}
|
||||
b := &B{A: a, C: 123}
|
||||
|
||||
s := Fields(b)
|
||||
|
||||
if len(s) != 2 {
|
||||
t.Errorf("Fields should omit nested struct. Expecting 2 got: %d", len(s))
|
||||
}
|
||||
|
||||
inSlice := func(val interface{}) bool {
|
||||
for _, v := range s {
|
||||
if reflect.DeepEqual(v, val) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
for _, val := range []interface{}{"A", "C"} {
|
||||
if !inSlice(val) {
|
||||
t.Errorf("Fields should have the value %v", val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFields_Nested(t *testing.T) {
|
||||
type A struct {
|
||||
Name string
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user