-
Notifications
You must be signed in to change notification settings - Fork 2
/
reflect.go
62 lines (52 loc) · 1.31 KB
/
reflect.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package karma
import (
"fmt"
"reflect"
"strconv"
)
func DescribeDeep(prefixKey string, obj interface{}) *Context {
ctx := &Context{}
describeDeep(ctx, obj, prefixKey, "")
return ctx
}
func describeDeep(ctx *Context, obj interface{}, prefix string, key string) {
resource := reflect.Indirect(reflect.ValueOf(obj))
for resource.Kind() == reflect.Ptr {
resource = resource.Elem()
}
prefixKey := joinPrefixKey(prefix, key)
resourceType := resource.Type()
switch resource.Kind() {
case reflect.Struct:
for index := 0; index < resourceType.NumField(); index++ {
resourceField := resource.Field(index)
if !resourceField.CanInterface() {
continue
}
structField := resourceType.Field(index)
fieldName := string(structField.Name)
describeDeep(ctx, resourceField.Interface(), prefixKey, fieldName)
}
case reflect.Slice:
for i := 0; i < resource.Len(); i++ {
field := reflect.Indirect(resource.Index(i))
if !field.CanInterface() {
continue
}
describeDeep(ctx, field.Interface(), prefixKey, "["+strconv.Itoa(i)+"]")
}
default:
*ctx = *ctx.Describe(prefixKey, fmt.Sprint(obj))
}
}
func joinPrefixKey(prefix string, key string) string {
result := prefix
if key != "" {
if key[0] == '[' {
result = result + key
} else {
result = result + "." + key
}
}
return result
}