author | Mikael Berthe <mikael@lilotux.net> |
Tue, 23 Aug 2022 22:39:43 +0200 | |
changeset 260 | 445e01aede7e |
parent 256 | 6d9efbef00a9 |
permissions | -rw-r--r-- |
242
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
1 |
package mapstructure |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
2 |
|
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
3 |
import ( |
256 | 4 |
"encoding" |
242
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
5 |
"errors" |
251 | 6 |
"fmt" |
7 |
"net" |
|
242
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
8 |
"reflect" |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
9 |
"strconv" |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
10 |
"strings" |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
11 |
"time" |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
12 |
) |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
13 |
|
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
14 |
// typedDecodeHook takes a raw DecodeHookFunc (an interface{}) and turns |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
15 |
// it into the proper DecodeHookFunc type, such as DecodeHookFuncType. |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
16 |
func typedDecodeHook(h DecodeHookFunc) DecodeHookFunc { |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
17 |
// Create variables here so we can reference them with the reflect pkg |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
18 |
var f1 DecodeHookFuncType |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
19 |
var f2 DecodeHookFuncKind |
256 | 20 |
var f3 DecodeHookFuncValue |
242
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
21 |
|
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
22 |
// Fill in the variables into this interface and the rest is done |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
23 |
// automatically using the reflect package. |
256 | 24 |
potential := []interface{}{f1, f2, f3} |
242
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
25 |
|
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
26 |
v := reflect.ValueOf(h) |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
27 |
vt := v.Type() |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
28 |
for _, raw := range potential { |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
29 |
pt := reflect.ValueOf(raw).Type() |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
30 |
if vt.ConvertibleTo(pt) { |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
31 |
return v.Convert(pt).Interface() |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
32 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
33 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
34 |
|
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
35 |
return nil |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
36 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
37 |
|
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
38 |
// DecodeHookExec executes the given decode hook. This should be used |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
39 |
// since it'll naturally degrade to the older backwards compatible DecodeHookFunc |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
40 |
// that took reflect.Kind instead of reflect.Type. |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
41 |
func DecodeHookExec( |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
42 |
raw DecodeHookFunc, |
256 | 43 |
from reflect.Value, to reflect.Value) (interface{}, error) { |
44 |
||
242
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
45 |
switch f := typedDecodeHook(raw).(type) { |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
46 |
case DecodeHookFuncType: |
256 | 47 |
return f(from.Type(), to.Type(), from.Interface()) |
242
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
48 |
case DecodeHookFuncKind: |
256 | 49 |
return f(from.Kind(), to.Kind(), from.Interface()) |
50 |
case DecodeHookFuncValue: |
|
51 |
return f(from, to) |
|
242
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
52 |
default: |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
53 |
return nil, errors.New("invalid decode hook signature") |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
54 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
55 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
56 |
|
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
57 |
// ComposeDecodeHookFunc creates a single DecodeHookFunc that |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
58 |
// automatically composes multiple DecodeHookFuncs. |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
59 |
// |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
60 |
// The composed funcs are called in order, with the result of the |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
61 |
// previous transformation. |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
62 |
func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc { |
256 | 63 |
return func(f reflect.Value, t reflect.Value) (interface{}, error) { |
242
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
64 |
var err error |
260 | 65 |
data := f.Interface() |
66 |
||
256 | 67 |
newFrom := f |
242
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
68 |
for _, f1 := range fs { |
256 | 69 |
data, err = DecodeHookExec(f1, newFrom, t) |
242
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
70 |
if err != nil { |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
71 |
return nil, err |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
72 |
} |
256 | 73 |
newFrom = reflect.ValueOf(data) |
242
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
74 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
75 |
|
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
76 |
return data, nil |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
77 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
78 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
79 |
|
260 | 80 |
// OrComposeDecodeHookFunc executes all input hook functions until one of them returns no error. In that case its value is returned. |
81 |
// If all hooks return an error, OrComposeDecodeHookFunc returns an error concatenating all error messages. |
|
82 |
func OrComposeDecodeHookFunc(ff ...DecodeHookFunc) DecodeHookFunc { |
|
83 |
return func(a, b reflect.Value) (interface{}, error) { |
|
84 |
var allErrs string |
|
85 |
var out interface{} |
|
86 |
var err error |
|
87 |
||
88 |
for _, f := range ff { |
|
89 |
out, err = DecodeHookExec(f, a, b) |
|
90 |
if err != nil { |
|
91 |
allErrs += err.Error() + "\n" |
|
92 |
continue |
|
93 |
} |
|
94 |
||
95 |
return out, nil |
|
96 |
} |
|
97 |
||
98 |
return nil, errors.New(allErrs) |
|
99 |
} |
|
100 |
} |
|
101 |
||
242
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
102 |
// StringToSliceHookFunc returns a DecodeHookFunc that converts |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
103 |
// string to []string by splitting on the given sep. |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
104 |
func StringToSliceHookFunc(sep string) DecodeHookFunc { |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
105 |
return func( |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
106 |
f reflect.Kind, |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
107 |
t reflect.Kind, |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
108 |
data interface{}) (interface{}, error) { |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
109 |
if f != reflect.String || t != reflect.Slice { |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
110 |
return data, nil |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
111 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
112 |
|
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
113 |
raw := data.(string) |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
114 |
if raw == "" { |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
115 |
return []string{}, nil |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
116 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
117 |
|
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
118 |
return strings.Split(raw, sep), nil |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
119 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
120 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
121 |
|
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
122 |
// StringToTimeDurationHookFunc returns a DecodeHookFunc that converts |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
123 |
// strings to time.Duration. |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
124 |
func StringToTimeDurationHookFunc() DecodeHookFunc { |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
125 |
return func( |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
126 |
f reflect.Type, |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
127 |
t reflect.Type, |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
128 |
data interface{}) (interface{}, error) { |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
129 |
if f.Kind() != reflect.String { |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
130 |
return data, nil |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
131 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
132 |
if t != reflect.TypeOf(time.Duration(5)) { |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
133 |
return data, nil |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
134 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
135 |
|
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
136 |
// Convert it by parsing |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
137 |
return time.ParseDuration(data.(string)) |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
138 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
139 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
140 |
|
251 | 141 |
// StringToIPHookFunc returns a DecodeHookFunc that converts |
142 |
// strings to net.IP |
|
143 |
func StringToIPHookFunc() DecodeHookFunc { |
|
144 |
return func( |
|
145 |
f reflect.Type, |
|
146 |
t reflect.Type, |
|
147 |
data interface{}) (interface{}, error) { |
|
148 |
if f.Kind() != reflect.String { |
|
149 |
return data, nil |
|
150 |
} |
|
151 |
if t != reflect.TypeOf(net.IP{}) { |
|
152 |
return data, nil |
|
153 |
} |
|
154 |
||
155 |
// Convert it by parsing |
|
156 |
ip := net.ParseIP(data.(string)) |
|
157 |
if ip == nil { |
|
158 |
return net.IP{}, fmt.Errorf("failed parsing ip %v", data) |
|
159 |
} |
|
160 |
||
161 |
return ip, nil |
|
162 |
} |
|
163 |
} |
|
164 |
||
165 |
// StringToIPNetHookFunc returns a DecodeHookFunc that converts |
|
166 |
// strings to net.IPNet |
|
167 |
func StringToIPNetHookFunc() DecodeHookFunc { |
|
168 |
return func( |
|
169 |
f reflect.Type, |
|
170 |
t reflect.Type, |
|
171 |
data interface{}) (interface{}, error) { |
|
172 |
if f.Kind() != reflect.String { |
|
173 |
return data, nil |
|
174 |
} |
|
175 |
if t != reflect.TypeOf(net.IPNet{}) { |
|
176 |
return data, nil |
|
177 |
} |
|
178 |
||
179 |
// Convert it by parsing |
|
180 |
_, net, err := net.ParseCIDR(data.(string)) |
|
181 |
return net, err |
|
182 |
} |
|
183 |
} |
|
184 |
||
242
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
185 |
// StringToTimeHookFunc returns a DecodeHookFunc that converts |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
186 |
// strings to time.Time. |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
187 |
func StringToTimeHookFunc(layout string) DecodeHookFunc { |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
188 |
return func( |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
189 |
f reflect.Type, |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
190 |
t reflect.Type, |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
191 |
data interface{}) (interface{}, error) { |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
192 |
if f.Kind() != reflect.String { |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
193 |
return data, nil |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
194 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
195 |
if t != reflect.TypeOf(time.Time{}) { |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
196 |
return data, nil |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
197 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
198 |
|
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
199 |
// Convert it by parsing |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
200 |
return time.Parse(layout, data.(string)) |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
201 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
202 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
203 |
|
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
204 |
// WeaklyTypedHook is a DecodeHookFunc which adds support for weak typing to |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
205 |
// the decoder. |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
206 |
// |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
207 |
// Note that this is significantly different from the WeaklyTypedInput option |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
208 |
// of the DecoderConfig. |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
209 |
func WeaklyTypedHook( |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
210 |
f reflect.Kind, |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
211 |
t reflect.Kind, |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
212 |
data interface{}) (interface{}, error) { |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
213 |
dataVal := reflect.ValueOf(data) |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
214 |
switch t { |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
215 |
case reflect.String: |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
216 |
switch f { |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
217 |
case reflect.Bool: |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
218 |
if dataVal.Bool() { |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
219 |
return "1", nil |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
220 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
221 |
return "0", nil |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
222 |
case reflect.Float32: |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
223 |
return strconv.FormatFloat(dataVal.Float(), 'f', -1, 64), nil |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
224 |
case reflect.Int: |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
225 |
return strconv.FormatInt(dataVal.Int(), 10), nil |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
226 |
case reflect.Slice: |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
227 |
dataType := dataVal.Type() |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
228 |
elemKind := dataType.Elem().Kind() |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
229 |
if elemKind == reflect.Uint8 { |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
230 |
return string(dataVal.Interface().([]uint8)), nil |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
231 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
232 |
case reflect.Uint: |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
233 |
return strconv.FormatUint(dataVal.Uint(), 10), nil |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
234 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
235 |
} |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
236 |
|
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
237 |
return data, nil |
2a9ec03fe5a1
Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
238 |
} |
256 | 239 |
|
240 |
func RecursiveStructToMapHookFunc() DecodeHookFunc { |
|
241 |
return func(f reflect.Value, t reflect.Value) (interface{}, error) { |
|
242 |
if f.Kind() != reflect.Struct { |
|
243 |
return f.Interface(), nil |
|
244 |
} |
|
245 |
||
246 |
var i interface{} = struct{}{} |
|
247 |
if t.Type() != reflect.TypeOf(&i).Elem() { |
|
248 |
return f.Interface(), nil |
|
249 |
} |
|
250 |
||
251 |
m := make(map[string]interface{}) |
|
252 |
t.Set(reflect.ValueOf(m)) |
|
253 |
||
254 |
return f.Interface(), nil |
|
255 |
} |
|
256 |
} |
|
257 |
||
258 |
// TextUnmarshallerHookFunc returns a DecodeHookFunc that applies |
|
259 |
// strings to the UnmarshalText function, when the target type |
|
260 |
// implements the encoding.TextUnmarshaler interface |
|
261 |
func TextUnmarshallerHookFunc() DecodeHookFuncType { |
|
262 |
return func( |
|
263 |
f reflect.Type, |
|
264 |
t reflect.Type, |
|
265 |
data interface{}) (interface{}, error) { |
|
266 |
if f.Kind() != reflect.String { |
|
267 |
return data, nil |
|
268 |
} |
|
269 |
result := reflect.New(t).Interface() |
|
270 |
unmarshaller, ok := result.(encoding.TextUnmarshaler) |
|
271 |
if !ok { |
|
272 |
return data, nil |
|
273 |
} |
|
274 |
if err := unmarshaller.UnmarshalText([]byte(data.(string))); err != nil { |
|
275 |
return nil, err |
|
276 |
} |
|
277 |
return result, nil |
|
278 |
} |
|
279 |
} |