-
Notifications
You must be signed in to change notification settings - Fork 3
/
reflect.go
111 lines (100 loc) · 2.42 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
103
104
105
106
107
108
109
110
111
package sqlm
import (
"reflect"
)
var derefCount int64 = 0
var flatCount int64 = 0
func deRef(i interface{}) interface{} {
if i == nil {
return i
}
derefCount += 1
typeOfI := reflect.TypeOf(i)
switch typeOfI.Kind() {
case reflect.Ptr:
return deRef(reflect.ValueOf(i).Elem().Interface())
default:
return i
}
}
// flat v into list, and return list value
func flatInto(v reflect.Value, result reflect.Value) reflect.Value {
kindOfI := v.Kind()
switch kindOfI {
case reflect.Slice, reflect.Array:
vLen := v.Len()
if vLen == 1 {
vItem := v.Index(0)
if vItem.Kind() == reflect.Interface {
vElem := vItem.Elem()
vElemKind := vElem.Kind()
if vElemKind == reflect.Slice || vElemKind == reflect.Array {
for internalIndex := 0; internalIndex < vElem.Len(); internalIndex++ {
result = flatInto(vElem.Index(internalIndex), result)
}
} else {
result = reflect.Append(result, vItem)
}
} else {
result = reflect.Append(result, vItem)
}
return result
}
for index := 0; index < vLen; index++ {
vItem := v.Index(index)
if vItem.Kind() == reflect.Interface {
vElem := vItem.Elem()
if vElem.Kind() == reflect.Slice || vElem.Kind() == reflect.Array {
for internalIndex := 0; internalIndex < vElem.Len(); internalIndex++ {
internalElem := vItem.Elem().Index(internalIndex)
result = flatInto(internalElem, result)
}
} else {
result = reflect.Append(result, vItem)
}
} else {
result = reflect.Append(result, vItem)
}
}
return result
default:
result = reflect.Append(result, v)
return result
}
}
func flat(list []interface{}, i interface{}) []interface{} {
flatCount += 1
kindOfI := reflect.TypeOf(i).Kind()
switch kindOfI {
case reflect.Slice, reflect.Array:
valueOfI := reflect.ValueOf(i)
result := reflect.ValueOf(list)
result = flatInto(valueOfI, result)
return result.Interface().([]interface{})
default:
return append(list, i)
}
}
func assign(target interface{}, value interface{}) error {
switch t := target.(type) {
case *string:
*t = deRef(value).(string)
case *int:
*t = deRef(value).(int)
case *int8:
*t = deRef(value).(int8)
case *int16:
*t = deRef(value).(int16)
case *int32:
*t = deRef(value).(int32)
case *int64:
*t = deRef(value).(int64)
case *float32:
*t = deRef(value).(float32)
case *float64:
*t = deRef(value).(float64)
case *interface{}:
*t = deRef(value)
}
return nil
}