diff --git a/util/reflect/reflect.go b/util/reflect/reflect.go index b39c2c40..8b7ed526 100644 --- a/util/reflect/reflect.go +++ b/util/reflect/reflect.go @@ -65,8 +65,25 @@ func IsEmpty(v reflect.Value) bool { return v.IsNil() case reflect.Invalid: return true + case reflect.Struct: + var ok bool + for i := 0; i < v.NumField(); i++ { + ok = IsEmpty(v.FieldByIndex([]int{i})) + if !ok { + return false + } + } + default: + fmt.Printf("%#+v\n", v) + return false } - return false + return true +} + +// IsZero returns true if struct is zero (not have any defined values) +func IsZero(src interface{}) bool { + v := reflect.ValueOf(src) + return IsEmpty(v) } // Zero creates new zero interface diff --git a/util/reflect/reflect_test.go b/util/reflect/reflect_test.go index 68cf9e9c..7b3e95ae 100644 --- a/util/reflect/reflect_test.go +++ b/util/reflect/reflect_test.go @@ -43,3 +43,50 @@ func TestURLVars(t *testing.T) { } _ = mp } + +func TestIsZero(t *testing.T) { + testStr1 := struct { + Name string + Value string + Nested struct { + NestedName string + } + }{ + Name: "test_name", + Value: "test_value", + } + testStr1.Nested.NestedName = "nested_name" + + if ok := IsZero(testStr1); ok { + t.Fatalf("zero ret on non zero struct: %#+v", testStr1) + } + + testStr1.Name = "" + testStr1.Value = "" + testStr1.Nested.NestedName = "" + if ok := IsZero(testStr1); !ok { + t.Fatalf("non zero ret on zero struct: %#+v", testStr1) + } + + type testStr3 struct { + Nested string + } + type testStr2 struct { + Name string + Nested *testStr3 + } + vtest := &testStr2{ + Name: "test_name", + Nested: &testStr3{Nested: "nested_name"}, + } + if ok := IsZero(vtest); ok { + t.Fatalf("zero ret on non zero struct: %#+v", vtest) + } + vtest.Nested = nil + vtest.Name = "" + if ok := IsZero(vtest); !ok { + t.Fatalf("non zero ret on zero struct: %#+v", vtest) + } + + //t.Logf("XX %#+v\n", ok) +}