structure: add omitnested support to IsZero and HasZero

This commit is contained in:
Fatih Arslan 2014-08-08 11:49:06 +03:00
parent 72596462dd
commit 1b32eb1316
3 changed files with 57 additions and 3 deletions

View File

@ -134,7 +134,9 @@ func IsZero(s interface{}) bool {
for _, field := range fields {
val := v.FieldByName(field.Name)
if IsStruct(val.Interface()) {
_, tagOpts := parseTag(field.Tag.Get(DefaultTagName))
if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") {
ok := IsZero(val.Interface())
if !ok {
return false
@ -171,7 +173,10 @@ func HasZero(s interface{}) bool {
for _, field := range fields {
val := v.FieldByName(field.Name)
if IsStruct(val.Interface()) {
_, tagOpts := parseTag(field.Tag.Get(DefaultTagName))
if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") {
ok := HasZero(val.Interface())
if ok {
return true

View File

@ -548,6 +548,34 @@ func TestIsZero(t *testing.T) {
}
}
func TestIsZero_OmitNested(t *testing.T) {
type A struct {
Name string
D string
}
a := A{Name: "example"}
type B struct {
A A `structure:",omitnested"`
C int
}
b := &B{A: a, C: 123}
ok := IsZero(b)
if ok {
t.Error("IsZero should return false because A, B and C are initialized")
}
aZero := A{}
bZero := &B{A: aZero}
ok = IsZero(bZero)
if !ok {
t.Error("IsZero should return true because neither A nor B is initialized")
}
}
func TestIsZero_Nested(t *testing.T) {
type A struct {
Name string
@ -647,6 +675,27 @@ func TestHasZero(t *testing.T) {
}
}
func TestHasZero_OmitNested(t *testing.T) {
type A struct {
Name string
D string
}
a := A{Name: "example"}
type B struct {
A A `structure:",omitnested"`
C int
}
b := &B{A: a, C: 123}
// Because the Field A inside B is omitted HasZero should return false
// because it will stop iterating deeper andnot going to lookup for D
ok := HasZero(b)
if ok {
t.Error("HasZero should return false because A and C are initialized")
}
}
func TestHasZero_Nested(t *testing.T) {
type A struct {
Name string

View File

@ -5,7 +5,7 @@ import "strings"
// tagOptions contains a slice of tag options
type tagOptions []string
// Has returns true if the given opt is available inside the slice.
// Has returns true if the given optiton is available in tagOptions
func (t tagOptions) Has(opt string) bool {
for _, tagOpt := range t {
if tagOpt == opt {