Created
September 25, 2017 13:36
-
-
Save kaleocheng/53f4b6bdd4d80c008bc9d79e96546b26 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package valid | |
import ( | |
"reflect" | |
) | |
const tagName = "valid" | |
func IsZero(x interface{}) bool { | |
return reflect.DeepEqual(x, reflect.Zero(reflect.TypeOf(x)).Interface()) | |
} | |
func Valid(obj interface{}) bool { | |
ok := true | |
original := reflect.ValueOf(obj) | |
validRecursive(original, &ok) | |
return ok | |
} | |
func validRecursive(original reflect.Value, ok *bool) { | |
switch original.Kind() { | |
case reflect.Ptr: | |
originalValue := original.Elem() | |
// Check if the pointer is nil | |
if !originalValue.IsValid() { | |
*ok = false | |
return | |
} | |
validRecursive(originalValue, ok) | |
case reflect.Interface: | |
originalValue := original.Elem() | |
validRecursive(originalValue, ok) | |
case reflect.Struct: | |
for i := 0; i < original.NumField(); i++ { | |
tag := original.Type().Field(i).Tag.Get(tagName) | |
// Skip if tag is not defined or ignored | |
if tag == "" || tag == "-" { | |
continue | |
} | |
validRecursive(original.Field(i), ok) | |
} | |
case reflect.Slice: | |
for i := 0; i < original.Len(); i++ { | |
validRecursive(original.Index(i), ok) | |
} | |
case reflect.Map: | |
for _, key := range original.MapKeys() { | |
originalValue := original.MapIndex(key) | |
validRecursive(originalValue, ok) | |
} | |
// We don't check the bool value | |
case reflect.Bool: | |
break | |
// And everything else will simply be taken from the original | |
default: | |
if IsZero(original.Interface()) { | |
*ok = false | |
return | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment