/
reflect.go
102 lines (78 loc) · 1.92 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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package faunadb
import "reflect"
func structToMap(aStruct reflect.Value) map[string]interface{} {
res := make(map[string]interface{}, aStruct.NumField())
if expStructFields, err := exportedStructFields(aStruct); err == nil {
for key, value := range expStructFields {
res[key] = value.Interface()
}
}
return res
}
func exportedStructFields(aStruct reflect.Value) (map[string]reflect.Value, error) {
fields := make(map[string]reflect.Value)
aStructType := aStruct.Type()
for i, size := 0, aStruct.NumField(); i < size; i++ {
field := aStruct.Field(i)
if !field.CanInterface() {
continue
}
fieldName, ignore, omitempty, err := parseTag(aStructType.Field(i))
if err != nil {
return nil, err
}
if omitempty && isEmptyValue(field) {
continue
}
if !ignore && fieldName != "" {
fields[fieldName] = field
}
}
return fields, nil
}
func indirectValue(i interface{}) (reflect.Value, reflect.Type) {
var value reflect.Value
if reflected, ok := i.(reflect.Value); ok {
value = reflected
} else {
value = reflect.ValueOf(i)
}
for {
if value.Kind() == reflect.Interface && !value.IsNil() {
elem := value.Elem()
if elem.IsValid() {
value = elem
continue
}
}
if value.Kind() != reflect.Ptr {
break
}
if value.IsNil() {
if value.CanSet() {
value.Set(reflect.New(value.Type().Elem()))
} else {
break
}
}
value = value.Elem()
}
return value, value.Type()
}
func allStructFields(aStruct reflect.Value) map[string]reflect.Value {
fields := make(map[string]reflect.Value)
aStructType := aStruct.Type()
for i, size := 0, aStruct.NumField(); i < size; i++ {
field := aStruct.Field(i)
structTypeField := aStructType.Field(i)
if !field.CanInterface() {
continue
}
fieldName, ignore, _, _ := parseTag(aStructType.Field(i))
if !ignore && fieldName != "" {
fields[fieldName] = field
}
fields[structTypeField.Name] = field
}
return fields
}