-
-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathtraverse.go
113 lines (89 loc) · 1.94 KB
/
traverse.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
112
113
package goconfig
import (
"reflect"
"strings"
)
type callback func(i item)
type item struct {
FieldName string
Usage string
Ptr interface{}
Kind reflect.Kind
Path []string
Value reflect.Value
Tags reflect.StructTag
}
func traverse(c interface{}, f callback) {
traverse_recursive(c, f, []string{})
}
func traverse_recursive(c interface{}, f callback, p []string) {
t := reflect.ValueOf(c)
// Follow pointers
for reflect.Ptr == t.Kind() {
t = t.Elem()
}
for i := 0; i < t.NumField(); i++ {
field := t.Type().Field(i)
name := field.Name
value := t.Field(i)
usage := field.Tag.Get("usage")
ptr := value.Addr().Interface()
kind := value.Kind()
pr := p // parents to pass recursively
if !field.Anonymous {
pr = append(p, strings.ToLower(name))
}
name_path := strings.Join(p, ".")
if reflect.Struct == kind {
traverse_recursive(ptr, f, pr)
} else if reflect.Slice == kind {
//panic("Slice is not supported by goconfig at this moment.")
f(item{
FieldName: name,
Usage: usage,
Ptr: ptr,
Kind: kind,
Path: pr,
Value: value,
})
traverse_array(ptr, f, pr)
} else {
f(item{
FieldName: name,
Usage: usage,
Ptr: ptr,
Kind: kind,
Path: pr,
Value: value,
})
}
values[name_path] = ptr
//p = p[0 : len(p)-1]
}
}
func traverse_array(c interface{}, f callback, p []string) {
}
func traverse_json(c interface{}, f callback) {
t := reflect.ValueOf(c)
// Follow pointers
for reflect.Ptr == t.Kind() {
t = t.Elem()
}
for i := 0; i < t.NumField(); i++ {
field := t.Type().Field(i)
name := field.Name
value := t.Field(i)
usage := field.Tag.Get("usage")
ptr := value.Addr().Interface()
kind := value.Kind()
tags := field.Tag
f(item{
FieldName: name,
Usage: usage,
Ptr: ptr,
Kind: kind,
Value: value,
Tags: tags,
})
}
}