diff options
Diffstat (limited to 'vendor/github.com/mitchellh')
21 files changed, 2619 insertions, 0 deletions
diff --git a/vendor/github.com/mitchellh/copystructure/LICENSE b/vendor/github.com/mitchellh/copystructure/LICENSE new file mode 100644 index 0000000..2298515 --- /dev/null +++ b/vendor/github.com/mitchellh/copystructure/LICENSE | |||
@@ -0,0 +1,21 @@ | |||
1 | The MIT License (MIT) | ||
2 | |||
3 | Copyright (c) 2014 Mitchell Hashimoto | ||
4 | |||
5 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
6 | of this software and associated documentation files (the "Software"), to deal | ||
7 | in the Software without restriction, including without limitation the rights | ||
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
9 | copies of the Software, and to permit persons to whom the Software is | ||
10 | furnished to do so, subject to the following conditions: | ||
11 | |||
12 | The above copyright notice and this permission notice shall be included in | ||
13 | all copies or substantial portions of the Software. | ||
14 | |||
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
21 | THE SOFTWARE. | ||
diff --git a/vendor/github.com/mitchellh/copystructure/README.md b/vendor/github.com/mitchellh/copystructure/README.md new file mode 100644 index 0000000..bcb8c8d --- /dev/null +++ b/vendor/github.com/mitchellh/copystructure/README.md | |||
@@ -0,0 +1,21 @@ | |||
1 | # copystructure | ||
2 | |||
3 | copystructure is a Go library for deep copying values in Go. | ||
4 | |||
5 | This allows you to copy Go values that may contain reference values | ||
6 | such as maps, slices, or pointers, and copy their data as well instead | ||
7 | of just their references. | ||
8 | |||
9 | ## Installation | ||
10 | |||
11 | Standard `go get`: | ||
12 | |||
13 | ``` | ||
14 | $ go get github.com/mitchellh/copystructure | ||
15 | ``` | ||
16 | |||
17 | ## Usage & Example | ||
18 | |||
19 | For usage and examples see the [Godoc](http://godoc.org/github.com/mitchellh/copystructure). | ||
20 | |||
21 | The `Copy` function has examples associated with it there. | ||
diff --git a/vendor/github.com/mitchellh/copystructure/copier_time.go b/vendor/github.com/mitchellh/copystructure/copier_time.go new file mode 100644 index 0000000..db6a6aa --- /dev/null +++ b/vendor/github.com/mitchellh/copystructure/copier_time.go | |||
@@ -0,0 +1,15 @@ | |||
1 | package copystructure | ||
2 | |||
3 | import ( | ||
4 | "reflect" | ||
5 | "time" | ||
6 | ) | ||
7 | |||
8 | func init() { | ||
9 | Copiers[reflect.TypeOf(time.Time{})] = timeCopier | ||
10 | } | ||
11 | |||
12 | func timeCopier(v interface{}) (interface{}, error) { | ||
13 | // Just... copy it. | ||
14 | return v.(time.Time), nil | ||
15 | } | ||
diff --git a/vendor/github.com/mitchellh/copystructure/copystructure.go b/vendor/github.com/mitchellh/copystructure/copystructure.go new file mode 100644 index 0000000..0e725ea --- /dev/null +++ b/vendor/github.com/mitchellh/copystructure/copystructure.go | |||
@@ -0,0 +1,477 @@ | |||
1 | package copystructure | ||
2 | |||
3 | import ( | ||
4 | "errors" | ||
5 | "reflect" | ||
6 | "sync" | ||
7 | |||
8 | "github.com/mitchellh/reflectwalk" | ||
9 | ) | ||
10 | |||
11 | // Copy returns a deep copy of v. | ||
12 | func Copy(v interface{}) (interface{}, error) { | ||
13 | return Config{}.Copy(v) | ||
14 | } | ||
15 | |||
16 | // CopierFunc is a function that knows how to deep copy a specific type. | ||
17 | // Register these globally with the Copiers variable. | ||
18 | type CopierFunc func(interface{}) (interface{}, error) | ||
19 | |||
20 | // Copiers is a map of types that behave specially when they are copied. | ||
21 | // If a type is found in this map while deep copying, this function | ||
22 | // will be called to copy it instead of attempting to copy all fields. | ||
23 | // | ||
24 | // The key should be the type, obtained using: reflect.TypeOf(value with type). | ||
25 | // | ||
26 | // It is unsafe to write to this map after Copies have started. If you | ||
27 | // are writing to this map while also copying, wrap all modifications to | ||
28 | // this map as well as to Copy in a mutex. | ||
29 | var Copiers map[reflect.Type]CopierFunc = make(map[reflect.Type]CopierFunc) | ||
30 | |||
31 | // Must is a helper that wraps a call to a function returning | ||
32 | // (interface{}, error) and panics if the error is non-nil. It is intended | ||
33 | // for use in variable initializations and should only be used when a copy | ||
34 | // error should be a crashing case. | ||
35 | func Must(v interface{}, err error) interface{} { | ||
36 | if err != nil { | ||
37 | panic("copy error: " + err.Error()) | ||
38 | } | ||
39 | |||
40 | return v | ||
41 | } | ||
42 | |||
43 | var errPointerRequired = errors.New("Copy argument must be a pointer when Lock is true") | ||
44 | |||
45 | type Config struct { | ||
46 | // Lock any types that are a sync.Locker and are not a mutex while copying. | ||
47 | // If there is an RLocker method, use that to get the sync.Locker. | ||
48 | Lock bool | ||
49 | |||
50 | // Copiers is a map of types associated with a CopierFunc. Use the global | ||
51 | // Copiers map if this is nil. | ||
52 | Copiers map[reflect.Type]CopierFunc | ||
53 | } | ||
54 | |||
55 | func (c Config) Copy(v interface{}) (interface{}, error) { | ||
56 | if c.Lock && reflect.ValueOf(v).Kind() != reflect.Ptr { | ||
57 | return nil, errPointerRequired | ||
58 | } | ||
59 | |||
60 | w := new(walker) | ||
61 | if c.Lock { | ||
62 | w.useLocks = true | ||
63 | } | ||
64 | |||
65 | if c.Copiers == nil { | ||
66 | c.Copiers = Copiers | ||
67 | } | ||
68 | |||
69 | err := reflectwalk.Walk(v, w) | ||
70 | if err != nil { | ||
71 | return nil, err | ||
72 | } | ||
73 | |||
74 | // Get the result. If the result is nil, then we want to turn it | ||
75 | // into a typed nil if we can. | ||
76 | result := w.Result | ||
77 | if result == nil { | ||
78 | val := reflect.ValueOf(v) | ||
79 | result = reflect.Indirect(reflect.New(val.Type())).Interface() | ||
80 | } | ||
81 | |||
82 | return result, nil | ||
83 | } | ||
84 | |||
85 | // Return the key used to index interfaces types we've seen. Store the number | ||
86 | // of pointers in the upper 32bits, and the depth in the lower 32bits. This is | ||
87 | // easy to calculate, easy to match a key with our current depth, and we don't | ||
88 | // need to deal with initializing and cleaning up nested maps or slices. | ||
89 | func ifaceKey(pointers, depth int) uint64 { | ||
90 | return uint64(pointers)<<32 | uint64(depth) | ||
91 | } | ||
92 | |||
93 | type walker struct { | ||
94 | Result interface{} | ||
95 | |||
96 | depth int | ||
97 | ignoreDepth int | ||
98 | vals []reflect.Value | ||
99 | cs []reflect.Value | ||
100 | |||
101 | // This stores the number of pointers we've walked over, indexed by depth. | ||
102 | ps []int | ||
103 | |||
104 | // If an interface is indirected by a pointer, we need to know the type of | ||
105 | // interface to create when creating the new value. Store the interface | ||
106 | // types here, indexed by both the walk depth and the number of pointers | ||
107 | // already seen at that depth. Use ifaceKey to calculate the proper uint64 | ||
108 | // value. | ||
109 | ifaceTypes map[uint64]reflect.Type | ||
110 | |||
111 | // any locks we've taken, indexed by depth | ||
112 | locks []sync.Locker | ||
113 | // take locks while walking the structure | ||
114 | useLocks bool | ||
115 | } | ||
116 | |||
117 | func (w *walker) Enter(l reflectwalk.Location) error { | ||
118 | w.depth++ | ||
119 | |||
120 | // ensure we have enough elements to index via w.depth | ||
121 | for w.depth >= len(w.locks) { | ||
122 | w.locks = append(w.locks, nil) | ||
123 | } | ||
124 | |||
125 | for len(w.ps) < w.depth+1 { | ||
126 | w.ps = append(w.ps, 0) | ||
127 | } | ||
128 | |||
129 | return nil | ||
130 | } | ||
131 | |||
132 | func (w *walker) Exit(l reflectwalk.Location) error { | ||
133 | locker := w.locks[w.depth] | ||
134 | w.locks[w.depth] = nil | ||
135 | if locker != nil { | ||
136 | defer locker.Unlock() | ||
137 | } | ||
138 | |||
139 | // clear out pointers and interfaces as we exit the stack | ||
140 | w.ps[w.depth] = 0 | ||
141 | |||
142 | for k := range w.ifaceTypes { | ||
143 | mask := uint64(^uint32(0)) | ||
144 | if k&mask == uint64(w.depth) { | ||
145 | delete(w.ifaceTypes, k) | ||
146 | } | ||
147 | } | ||
148 | |||
149 | w.depth-- | ||
150 | if w.ignoreDepth > w.depth { | ||
151 | w.ignoreDepth = 0 | ||
152 | } | ||
153 | |||
154 | if w.ignoring() { | ||
155 | return nil | ||
156 | } | ||
157 | |||
158 | switch l { | ||
159 | case reflectwalk.Map: | ||
160 | fallthrough | ||
161 | case reflectwalk.Slice: | ||
162 | // Pop map off our container | ||
163 | w.cs = w.cs[:len(w.cs)-1] | ||
164 | case reflectwalk.MapValue: | ||
165 | // Pop off the key and value | ||
166 | mv := w.valPop() | ||
167 | mk := w.valPop() | ||
168 | m := w.cs[len(w.cs)-1] | ||
169 | |||
170 | // If mv is the zero value, SetMapIndex deletes the key form the map, | ||
171 | // or in this case never adds it. We need to create a properly typed | ||
172 | // zero value so that this key can be set. | ||
173 | if !mv.IsValid() { | ||
174 | mv = reflect.Zero(m.Type().Elem()) | ||
175 | } | ||
176 | m.SetMapIndex(mk, mv) | ||
177 | case reflectwalk.SliceElem: | ||
178 | // Pop off the value and the index and set it on the slice | ||
179 | v := w.valPop() | ||
180 | i := w.valPop().Interface().(int) | ||
181 | if v.IsValid() { | ||
182 | s := w.cs[len(w.cs)-1] | ||
183 | se := s.Index(i) | ||
184 | if se.CanSet() { | ||
185 | se.Set(v) | ||
186 | } | ||
187 | } | ||
188 | case reflectwalk.Struct: | ||
189 | w.replacePointerMaybe() | ||
190 | |||
191 | // Remove the struct from the container stack | ||
192 | w.cs = w.cs[:len(w.cs)-1] | ||
193 | case reflectwalk.StructField: | ||
194 | // Pop off the value and the field | ||
195 | v := w.valPop() | ||
196 | f := w.valPop().Interface().(reflect.StructField) | ||
197 | if v.IsValid() { | ||
198 | s := w.cs[len(w.cs)-1] | ||
199 | sf := reflect.Indirect(s).FieldByName(f.Name) | ||
200 | |||
201 | if sf.CanSet() { | ||
202 | sf.Set(v) | ||
203 | } | ||
204 | } | ||
205 | case reflectwalk.WalkLoc: | ||
206 | // Clear out the slices for GC | ||
207 | w.cs = nil | ||
208 | w.vals = nil | ||
209 | } | ||
210 | |||
211 | return nil | ||
212 | } | ||
213 | |||
214 | func (w *walker) Map(m reflect.Value) error { | ||
215 | if w.ignoring() { | ||
216 | return nil | ||
217 | } | ||
218 | w.lock(m) | ||
219 | |||
220 | // Create the map. If the map itself is nil, then just make a nil map | ||
221 | var newMap reflect.Value | ||
222 | if m.IsNil() { | ||
223 | newMap = reflect.Indirect(reflect.New(m.Type())) | ||
224 | } else { | ||
225 | newMap = reflect.MakeMap(m.Type()) | ||
226 | } | ||
227 | |||
228 | w.cs = append(w.cs, newMap) | ||
229 | w.valPush(newMap) | ||
230 | return nil | ||
231 | } | ||
232 | |||
233 | func (w *walker) MapElem(m, k, v reflect.Value) error { | ||
234 | return nil | ||
235 | } | ||
236 | |||
237 | func (w *walker) PointerEnter(v bool) error { | ||
238 | if v { | ||
239 | w.ps[w.depth]++ | ||
240 | } | ||
241 | return nil | ||
242 | } | ||
243 | |||
244 | func (w *walker) PointerExit(v bool) error { | ||
245 | if v { | ||
246 | w.ps[w.depth]-- | ||
247 | } | ||
248 | return nil | ||
249 | } | ||
250 | |||
251 | func (w *walker) Interface(v reflect.Value) error { | ||
252 | if !v.IsValid() { | ||
253 | return nil | ||
254 | } | ||
255 | if w.ifaceTypes == nil { | ||
256 | w.ifaceTypes = make(map[uint64]reflect.Type) | ||
257 | } | ||
258 | |||
259 | w.ifaceTypes[ifaceKey(w.ps[w.depth], w.depth)] = v.Type() | ||
260 | return nil | ||
261 | } | ||
262 | |||
263 | func (w *walker) Primitive(v reflect.Value) error { | ||
264 | if w.ignoring() { | ||
265 | return nil | ||
266 | } | ||
267 | w.lock(v) | ||
268 | |||
269 | // IsValid verifies the v is non-zero and CanInterface verifies | ||
270 | // that we're allowed to read this value (unexported fields). | ||
271 | var newV reflect.Value | ||
272 | if v.IsValid() && v.CanInterface() { | ||
273 | newV = reflect.New(v.Type()) | ||
274 | newV.Elem().Set(v) | ||
275 | } | ||
276 | |||
277 | w.valPush(newV) | ||
278 | w.replacePointerMaybe() | ||
279 | return nil | ||
280 | } | ||
281 | |||
282 | func (w *walker) Slice(s reflect.Value) error { | ||
283 | if w.ignoring() { | ||
284 | return nil | ||
285 | } | ||
286 | w.lock(s) | ||
287 | |||
288 | var newS reflect.Value | ||
289 | if s.IsNil() { | ||
290 | newS = reflect.Indirect(reflect.New(s.Type())) | ||
291 | } else { | ||
292 | newS = reflect.MakeSlice(s.Type(), s.Len(), s.Cap()) | ||
293 | } | ||
294 | |||
295 | w.cs = append(w.cs, newS) | ||
296 | w.valPush(newS) | ||
297 | return nil | ||
298 | } | ||
299 | |||
300 | func (w *walker) SliceElem(i int, elem reflect.Value) error { | ||
301 | if w.ignoring() { | ||
302 | return nil | ||
303 | } | ||
304 | |||
305 | // We don't write the slice here because elem might still be | ||
306 | // arbitrarily complex. Just record the index and continue on. | ||
307 | w.valPush(reflect.ValueOf(i)) | ||
308 | |||
309 | return nil | ||
310 | } | ||
311 | |||
312 | func (w *walker) Struct(s reflect.Value) error { | ||
313 | if w.ignoring() { | ||
314 | return nil | ||
315 | } | ||
316 | w.lock(s) | ||
317 | |||
318 | var v reflect.Value | ||
319 | if c, ok := Copiers[s.Type()]; ok { | ||
320 | // We have a Copier for this struct, so we use that copier to | ||
321 | // get the copy, and we ignore anything deeper than this. | ||
322 | w.ignoreDepth = w.depth | ||
323 | |||
324 | dup, err := c(s.Interface()) | ||
325 | if err != nil { | ||
326 | return err | ||
327 | } | ||
328 | |||
329 | v = reflect.ValueOf(dup) | ||
330 | } else { | ||
331 | // No copier, we copy ourselves and allow reflectwalk to guide | ||
332 | // us deeper into the structure for copying. | ||
333 | v = reflect.New(s.Type()) | ||
334 | } | ||
335 | |||
336 | // Push the value onto the value stack for setting the struct field, | ||
337 | // and add the struct itself to the containers stack in case we walk | ||
338 | // deeper so that its own fields can be modified. | ||
339 | w.valPush(v) | ||
340 | w.cs = append(w.cs, v) | ||
341 | |||
342 | return nil | ||
343 | } | ||
344 | |||
345 | func (w *walker) StructField(f reflect.StructField, v reflect.Value) error { | ||
346 | if w.ignoring() { | ||
347 | return nil | ||
348 | } | ||
349 | |||
350 | // If PkgPath is non-empty, this is a private (unexported) field. | ||
351 | // We do not set this unexported since the Go runtime doesn't allow us. | ||
352 | if f.PkgPath != "" { | ||
353 | return reflectwalk.SkipEntry | ||
354 | } | ||
355 | |||
356 | // Push the field onto the stack, we'll handle it when we exit | ||
357 | // the struct field in Exit... | ||
358 | w.valPush(reflect.ValueOf(f)) | ||
359 | return nil | ||
360 | } | ||
361 | |||
362 | // ignore causes the walker to ignore any more values until we exit this on | ||
363 | func (w *walker) ignore() { | ||
364 | w.ignoreDepth = w.depth | ||
365 | } | ||
366 | |||
367 | func (w *walker) ignoring() bool { | ||
368 | return w.ignoreDepth > 0 && w.depth >= w.ignoreDepth | ||
369 | } | ||
370 | |||
371 | func (w *walker) pointerPeek() bool { | ||
372 | return w.ps[w.depth] > 0 | ||
373 | } | ||
374 | |||
375 | func (w *walker) valPop() reflect.Value { | ||
376 | result := w.vals[len(w.vals)-1] | ||
377 | w.vals = w.vals[:len(w.vals)-1] | ||
378 | |||
379 | // If we're out of values, that means we popped everything off. In | ||
380 | // this case, we reset the result so the next pushed value becomes | ||
381 | // the result. | ||
382 | if len(w.vals) == 0 { | ||
383 | w.Result = nil | ||
384 | } | ||
385 | |||
386 | return result | ||
387 | } | ||
388 | |||
389 | func (w *walker) valPush(v reflect.Value) { | ||
390 | w.vals = append(w.vals, v) | ||
391 | |||
392 | // If we haven't set the result yet, then this is the result since | ||
393 | // it is the first (outermost) value we're seeing. | ||
394 | if w.Result == nil && v.IsValid() { | ||
395 | w.Result = v.Interface() | ||
396 | } | ||
397 | } | ||
398 | |||
399 | func (w *walker) replacePointerMaybe() { | ||
400 | // Determine the last pointer value. If it is NOT a pointer, then | ||
401 | // we need to push that onto the stack. | ||
402 | if !w.pointerPeek() { | ||
403 | w.valPush(reflect.Indirect(w.valPop())) | ||
404 | return | ||
405 | } | ||
406 | |||
407 | v := w.valPop() | ||
408 | for i := 1; i < w.ps[w.depth]; i++ { | ||
409 | if iType, ok := w.ifaceTypes[ifaceKey(w.ps[w.depth]-i, w.depth)]; ok { | ||
410 | iface := reflect.New(iType).Elem() | ||
411 | iface.Set(v) | ||
412 | v = iface | ||
413 | } | ||
414 | |||
415 | p := reflect.New(v.Type()) | ||
416 | p.Elem().Set(v) | ||
417 | v = p | ||
418 | } | ||
419 | |||
420 | w.valPush(v) | ||
421 | } | ||
422 | |||
423 | // if this value is a Locker, lock it and add it to the locks slice | ||
424 | func (w *walker) lock(v reflect.Value) { | ||
425 | if !w.useLocks { | ||
426 | return | ||
427 | } | ||
428 | |||
429 | if !v.IsValid() || !v.CanInterface() { | ||
430 | return | ||
431 | } | ||
432 | |||
433 | type rlocker interface { | ||
434 | RLocker() sync.Locker | ||
435 | } | ||
436 | |||
437 | var locker sync.Locker | ||
438 | |||
439 | // We can't call Interface() on a value directly, since that requires | ||
440 | // a copy. This is OK, since the pointer to a value which is a sync.Locker | ||
441 | // is also a sync.Locker. | ||
442 | if v.Kind() == reflect.Ptr { | ||
443 | switch l := v.Interface().(type) { | ||
444 | case rlocker: | ||
445 | // don't lock a mutex directly | ||
446 | if _, ok := l.(*sync.RWMutex); !ok { | ||
447 | locker = l.RLocker() | ||
448 | } | ||
449 | case sync.Locker: | ||
450 | locker = l | ||
451 | } | ||
452 | } else if v.CanAddr() { | ||
453 | switch l := v.Addr().Interface().(type) { | ||
454 | case rlocker: | ||
455 | // don't lock a mutex directly | ||
456 | if _, ok := l.(*sync.RWMutex); !ok { | ||
457 | locker = l.RLocker() | ||
458 | } | ||
459 | case sync.Locker: | ||
460 | locker = l | ||
461 | } | ||
462 | } | ||
463 | |||
464 | // still no callable locker | ||
465 | if locker == nil { | ||
466 | return | ||
467 | } | ||
468 | |||
469 | // don't lock a mutex directly | ||
470 | switch locker.(type) { | ||
471 | case *sync.Mutex, *sync.RWMutex: | ||
472 | return | ||
473 | } | ||
474 | |||
475 | locker.Lock() | ||
476 | w.locks[w.depth] = locker | ||
477 | } | ||
diff --git a/vendor/github.com/mitchellh/go-homedir/LICENSE b/vendor/github.com/mitchellh/go-homedir/LICENSE new file mode 100644 index 0000000..f9c841a --- /dev/null +++ b/vendor/github.com/mitchellh/go-homedir/LICENSE | |||
@@ -0,0 +1,21 @@ | |||
1 | The MIT License (MIT) | ||
2 | |||
3 | Copyright (c) 2013 Mitchell Hashimoto | ||
4 | |||
5 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
6 | of this software and associated documentation files (the "Software"), to deal | ||
7 | in the Software without restriction, including without limitation the rights | ||
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
9 | copies of the Software, and to permit persons to whom the Software is | ||
10 | furnished to do so, subject to the following conditions: | ||
11 | |||
12 | The above copyright notice and this permission notice shall be included in | ||
13 | all copies or substantial portions of the Software. | ||
14 | |||
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
21 | THE SOFTWARE. | ||
diff --git a/vendor/github.com/mitchellh/go-homedir/README.md b/vendor/github.com/mitchellh/go-homedir/README.md new file mode 100644 index 0000000..d70706d --- /dev/null +++ b/vendor/github.com/mitchellh/go-homedir/README.md | |||
@@ -0,0 +1,14 @@ | |||
1 | # go-homedir | ||
2 | |||
3 | This is a Go library for detecting the user's home directory without | ||
4 | the use of cgo, so the library can be used in cross-compilation environments. | ||
5 | |||
6 | Usage is incredibly simple, just call `homedir.Dir()` to get the home directory | ||
7 | for a user, and `homedir.Expand()` to expand the `~` in a path to the home | ||
8 | directory. | ||
9 | |||
10 | **Why not just use `os/user`?** The built-in `os/user` package requires | ||
11 | cgo on Darwin systems. This means that any Go code that uses that package | ||
12 | cannot cross compile. But 99% of the time the use for `os/user` is just to | ||
13 | retrieve the home directory, which we can do for the current user without | ||
14 | cgo. This library does that, enabling cross-compilation. | ||
diff --git a/vendor/github.com/mitchellh/go-homedir/homedir.go b/vendor/github.com/mitchellh/go-homedir/homedir.go new file mode 100644 index 0000000..47e1f9e --- /dev/null +++ b/vendor/github.com/mitchellh/go-homedir/homedir.go | |||
@@ -0,0 +1,137 @@ | |||
1 | package homedir | ||
2 | |||
3 | import ( | ||
4 | "bytes" | ||
5 | "errors" | ||
6 | "os" | ||
7 | "os/exec" | ||
8 | "path/filepath" | ||
9 | "runtime" | ||
10 | "strconv" | ||
11 | "strings" | ||
12 | "sync" | ||
13 | ) | ||
14 | |||
15 | // DisableCache will disable caching of the home directory. Caching is enabled | ||
16 | // by default. | ||
17 | var DisableCache bool | ||
18 | |||
19 | var homedirCache string | ||
20 | var cacheLock sync.RWMutex | ||
21 | |||
22 | // Dir returns the home directory for the executing user. | ||
23 | // | ||
24 | // This uses an OS-specific method for discovering the home directory. | ||
25 | // An error is returned if a home directory cannot be detected. | ||
26 | func Dir() (string, error) { | ||
27 | if !DisableCache { | ||
28 | cacheLock.RLock() | ||
29 | cached := homedirCache | ||
30 | cacheLock.RUnlock() | ||
31 | if cached != "" { | ||
32 | return cached, nil | ||
33 | } | ||
34 | } | ||
35 | |||
36 | cacheLock.Lock() | ||
37 | defer cacheLock.Unlock() | ||
38 | |||
39 | var result string | ||
40 | var err error | ||
41 | if runtime.GOOS == "windows" { | ||
42 | result, err = dirWindows() | ||
43 | } else { | ||
44 | // Unix-like system, so just assume Unix | ||
45 | result, err = dirUnix() | ||
46 | } | ||
47 | |||
48 | if err != nil { | ||
49 | return "", err | ||
50 | } | ||
51 | homedirCache = result | ||
52 | return result, nil | ||
53 | } | ||
54 | |||
55 | // Expand expands the path to include the home directory if the path | ||
56 | // is prefixed with `~`. If it isn't prefixed with `~`, the path is | ||
57 | // returned as-is. | ||
58 | func Expand(path string) (string, error) { | ||
59 | if len(path) == 0 { | ||
60 | return path, nil | ||
61 | } | ||
62 | |||
63 | if path[0] != '~' { | ||
64 | return path, nil | ||
65 | } | ||
66 | |||
67 | if len(path) > 1 && path[1] != '/' && path[1] != '\\' { | ||
68 | return "", errors.New("cannot expand user-specific home dir") | ||
69 | } | ||
70 | |||
71 | dir, err := Dir() | ||
72 | if err != nil { | ||
73 | return "", err | ||
74 | } | ||
75 | |||
76 | return filepath.Join(dir, path[1:]), nil | ||
77 | } | ||
78 | |||
79 | func dirUnix() (string, error) { | ||
80 | // First prefer the HOME environmental variable | ||
81 | if home := os.Getenv("HOME"); home != "" { | ||
82 | return home, nil | ||
83 | } | ||
84 | |||
85 | // If that fails, try getent | ||
86 | var stdout bytes.Buffer | ||
87 | cmd := exec.Command("getent", "passwd", strconv.Itoa(os.Getuid())) | ||
88 | cmd.Stdout = &stdout | ||
89 | if err := cmd.Run(); err != nil { | ||
90 | // If the error is ErrNotFound, we ignore it. Otherwise, return it. | ||
91 | if err != exec.ErrNotFound { | ||
92 | return "", err | ||
93 | } | ||
94 | } else { | ||
95 | if passwd := strings.TrimSpace(stdout.String()); passwd != "" { | ||
96 | // username:password:uid:gid:gecos:home:shell | ||
97 | passwdParts := strings.SplitN(passwd, ":", 7) | ||
98 | if len(passwdParts) > 5 { | ||
99 | return passwdParts[5], nil | ||
100 | } | ||
101 | } | ||
102 | } | ||
103 | |||
104 | // If all else fails, try the shell | ||
105 | stdout.Reset() | ||
106 | cmd = exec.Command("sh", "-c", "cd && pwd") | ||
107 | cmd.Stdout = &stdout | ||
108 | if err := cmd.Run(); err != nil { | ||
109 | return "", err | ||
110 | } | ||
111 | |||
112 | result := strings.TrimSpace(stdout.String()) | ||
113 | if result == "" { | ||
114 | return "", errors.New("blank output when reading home directory") | ||
115 | } | ||
116 | |||
117 | return result, nil | ||
118 | } | ||
119 | |||
120 | func dirWindows() (string, error) { | ||
121 | // First prefer the HOME environmental variable | ||
122 | if home := os.Getenv("HOME"); home != "" { | ||
123 | return home, nil | ||
124 | } | ||
125 | |||
126 | drive := os.Getenv("HOMEDRIVE") | ||
127 | path := os.Getenv("HOMEPATH") | ||
128 | home := drive + path | ||
129 | if drive == "" || path == "" { | ||
130 | home = os.Getenv("USERPROFILE") | ||
131 | } | ||
132 | if home == "" { | ||
133 | return "", errors.New("HOMEDRIVE, HOMEPATH, and USERPROFILE are blank") | ||
134 | } | ||
135 | |||
136 | return home, nil | ||
137 | } | ||
diff --git a/vendor/github.com/mitchellh/hashstructure/LICENSE b/vendor/github.com/mitchellh/hashstructure/LICENSE new file mode 100644 index 0000000..a3866a2 --- /dev/null +++ b/vendor/github.com/mitchellh/hashstructure/LICENSE | |||
@@ -0,0 +1,21 @@ | |||
1 | The MIT License (MIT) | ||
2 | |||
3 | Copyright (c) 2016 Mitchell Hashimoto | ||
4 | |||
5 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
6 | of this software and associated documentation files (the "Software"), to deal | ||
7 | in the Software without restriction, including without limitation the rights | ||
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
9 | copies of the Software, and to permit persons to whom the Software is | ||
10 | furnished to do so, subject to the following conditions: | ||
11 | |||
12 | The above copyright notice and this permission notice shall be included in | ||
13 | all copies or substantial portions of the Software. | ||
14 | |||
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
21 | THE SOFTWARE. | ||
diff --git a/vendor/github.com/mitchellh/hashstructure/README.md b/vendor/github.com/mitchellh/hashstructure/README.md new file mode 100644 index 0000000..7d0de5b --- /dev/null +++ b/vendor/github.com/mitchellh/hashstructure/README.md | |||
@@ -0,0 +1,61 @@ | |||
1 | # hashstructure | ||
2 | |||
3 | hashstructure is a Go library for creating a unique hash value | ||
4 | for arbitrary values in Go. | ||
5 | |||
6 | This can be used to key values in a hash (for use in a map, set, etc.) | ||
7 | that are complex. The most common use case is comparing two values without | ||
8 | sending data across the network, caching values locally (de-dup), and so on. | ||
9 | |||
10 | ## Features | ||
11 | |||
12 | * Hash any arbitrary Go value, including complex types. | ||
13 | |||
14 | * Tag a struct field to ignore it and not affect the hash value. | ||
15 | |||
16 | * Tag a slice type struct field to treat it as a set where ordering | ||
17 | doesn't affect the hash code but the field itself is still taken into | ||
18 | account to create the hash value. | ||
19 | |||
20 | * Optionally specify a custom hash function to optimize for speed, collision | ||
21 | avoidance for your data set, etc. | ||
22 | |||
23 | ## Installation | ||
24 | |||
25 | Standard `go get`: | ||
26 | |||
27 | ``` | ||
28 | $ go get github.com/mitchellh/hashstructure | ||
29 | ``` | ||
30 | |||
31 | ## Usage & Example | ||
32 | |||
33 | For usage and examples see the [Godoc](http://godoc.org/github.com/mitchellh/hashstructure). | ||
34 | |||
35 | A quick code example is shown below: | ||
36 | |||
37 | |||
38 | type ComplexStruct struct { | ||
39 | Name string | ||
40 | Age uint | ||
41 | Metadata map[string]interface{} | ||
42 | } | ||
43 | |||
44 | v := ComplexStruct{ | ||
45 | Name: "mitchellh", | ||
46 | Age: 64, | ||
47 | Metadata: map[string]interface{}{ | ||
48 | "car": true, | ||
49 | "location": "California", | ||
50 | "siblings": []string{"Bob", "John"}, | ||
51 | }, | ||
52 | } | ||
53 | |||
54 | hash, err := hashstructure.Hash(v, nil) | ||
55 | if err != nil { | ||
56 | panic(err) | ||
57 | } | ||
58 | |||
59 | fmt.Printf("%d", hash) | ||
60 | // Output: | ||
61 | // 2307517237273902113 | ||
diff --git a/vendor/github.com/mitchellh/hashstructure/hashstructure.go b/vendor/github.com/mitchellh/hashstructure/hashstructure.go new file mode 100644 index 0000000..6f586fa --- /dev/null +++ b/vendor/github.com/mitchellh/hashstructure/hashstructure.go | |||
@@ -0,0 +1,323 @@ | |||
1 | package hashstructure | ||
2 | |||
3 | import ( | ||
4 | "encoding/binary" | ||
5 | "fmt" | ||
6 | "hash" | ||
7 | "hash/fnv" | ||
8 | "reflect" | ||
9 | ) | ||
10 | |||
11 | // HashOptions are options that are available for hashing. | ||
12 | type HashOptions struct { | ||
13 | // Hasher is the hash function to use. If this isn't set, it will | ||
14 | // default to FNV. | ||
15 | Hasher hash.Hash64 | ||
16 | |||
17 | // TagName is the struct tag to look at when hashing the structure. | ||
18 | // By default this is "hash". | ||
19 | TagName string | ||
20 | } | ||
21 | |||
22 | // Hash returns the hash value of an arbitrary value. | ||
23 | // | ||
24 | // If opts is nil, then default options will be used. See HashOptions | ||
25 | // for the default values. | ||
26 | // | ||
27 | // Notes on the value: | ||
28 | // | ||
29 | // * Unexported fields on structs are ignored and do not affect the | ||
30 | // hash value. | ||
31 | // | ||
32 | // * Adding an exported field to a struct with the zero value will change | ||
33 | // the hash value. | ||
34 | // | ||
35 | // For structs, the hashing can be controlled using tags. For example: | ||
36 | // | ||
37 | // struct { | ||
38 | // Name string | ||
39 | // UUID string `hash:"ignore"` | ||
40 | // } | ||
41 | // | ||
42 | // The available tag values are: | ||
43 | // | ||
44 | // * "ignore" - The field will be ignored and not affect the hash code. | ||
45 | // | ||
46 | // * "set" - The field will be treated as a set, where ordering doesn't | ||
47 | // affect the hash code. This only works for slices. | ||
48 | // | ||
49 | func Hash(v interface{}, opts *HashOptions) (uint64, error) { | ||
50 | // Create default options | ||
51 | if opts == nil { | ||
52 | opts = &HashOptions{} | ||
53 | } | ||
54 | if opts.Hasher == nil { | ||
55 | opts.Hasher = fnv.New64() | ||
56 | } | ||
57 | if opts.TagName == "" { | ||
58 | opts.TagName = "hash" | ||
59 | } | ||
60 | |||
61 | // Reset the hash | ||
62 | opts.Hasher.Reset() | ||
63 | |||
64 | // Create our walker and walk the structure | ||
65 | w := &walker{ | ||
66 | h: opts.Hasher, | ||
67 | tag: opts.TagName, | ||
68 | } | ||
69 | return w.visit(reflect.ValueOf(v), nil) | ||
70 | } | ||
71 | |||
72 | type walker struct { | ||
73 | h hash.Hash64 | ||
74 | tag string | ||
75 | } | ||
76 | |||
77 | type visitOpts struct { | ||
78 | // Flags are a bitmask of flags to affect behavior of this visit | ||
79 | Flags visitFlag | ||
80 | |||
81 | // Information about the struct containing this field | ||
82 | Struct interface{} | ||
83 | StructField string | ||
84 | } | ||
85 | |||
86 | func (w *walker) visit(v reflect.Value, opts *visitOpts) (uint64, error) { | ||
87 | // Loop since these can be wrapped in multiple layers of pointers | ||
88 | // and interfaces. | ||
89 | for { | ||
90 | // If we have an interface, dereference it. We have to do this up | ||
91 | // here because it might be a nil in there and the check below must | ||
92 | // catch that. | ||
93 | if v.Kind() == reflect.Interface { | ||
94 | v = v.Elem() | ||
95 | continue | ||
96 | } | ||
97 | |||
98 | if v.Kind() == reflect.Ptr { | ||
99 | v = reflect.Indirect(v) | ||
100 | continue | ||
101 | } | ||
102 | |||
103 | break | ||
104 | } | ||
105 | |||
106 | // If it is nil, treat it like a zero. | ||
107 | if !v.IsValid() { | ||
108 | var tmp int8 | ||
109 | v = reflect.ValueOf(tmp) | ||
110 | } | ||
111 | |||
112 | // Binary writing can use raw ints, we have to convert to | ||
113 | // a sized-int, we'll choose the largest... | ||
114 | switch v.Kind() { | ||
115 | case reflect.Int: | ||
116 | v = reflect.ValueOf(int64(v.Int())) | ||
117 | case reflect.Uint: | ||
118 | v = reflect.ValueOf(uint64(v.Uint())) | ||
119 | case reflect.Bool: | ||
120 | var tmp int8 | ||
121 | if v.Bool() { | ||
122 | tmp = 1 | ||
123 | } | ||
124 | v = reflect.ValueOf(tmp) | ||
125 | } | ||
126 | |||
127 | k := v.Kind() | ||
128 | |||
129 | // We can shortcut numeric values by directly binary writing them | ||
130 | if k >= reflect.Int && k <= reflect.Complex64 { | ||
131 | // A direct hash calculation | ||
132 | w.h.Reset() | ||
133 | err := binary.Write(w.h, binary.LittleEndian, v.Interface()) | ||
134 | return w.h.Sum64(), err | ||
135 | } | ||
136 | |||
137 | switch k { | ||
138 | case reflect.Array: | ||
139 | var h uint64 | ||
140 | l := v.Len() | ||
141 | for i := 0; i < l; i++ { | ||
142 | current, err := w.visit(v.Index(i), nil) | ||
143 | if err != nil { | ||
144 | return 0, err | ||
145 | } | ||
146 | |||
147 | h = hashUpdateOrdered(w.h, h, current) | ||
148 | } | ||
149 | |||
150 | return h, nil | ||
151 | |||
152 | case reflect.Map: | ||
153 | var includeMap IncludableMap | ||
154 | if opts != nil && opts.Struct != nil { | ||
155 | if v, ok := opts.Struct.(IncludableMap); ok { | ||
156 | includeMap = v | ||
157 | } | ||
158 | } | ||
159 | |||
160 | // Build the hash for the map. We do this by XOR-ing all the key | ||
161 | // and value hashes. This makes it deterministic despite ordering. | ||
162 | var h uint64 | ||
163 | for _, k := range v.MapKeys() { | ||
164 | v := v.MapIndex(k) | ||
165 | if includeMap != nil { | ||
166 | incl, err := includeMap.HashIncludeMap( | ||
167 | opts.StructField, k.Interface(), v.Interface()) | ||
168 | if err != nil { | ||
169 | return 0, err | ||
170 | } | ||
171 | if !incl { | ||
172 | continue | ||
173 | } | ||
174 | } | ||
175 | |||
176 | kh, err := w.visit(k, nil) | ||
177 | if err != nil { | ||
178 | return 0, err | ||
179 | } | ||
180 | vh, err := w.visit(v, nil) | ||
181 | if err != nil { | ||
182 | return 0, err | ||
183 | } | ||
184 | |||
185 | fieldHash := hashUpdateOrdered(w.h, kh, vh) | ||
186 | h = hashUpdateUnordered(h, fieldHash) | ||
187 | } | ||
188 | |||
189 | return h, nil | ||
190 | |||
191 | case reflect.Struct: | ||
192 | var include Includable | ||
193 | parent := v.Interface() | ||
194 | if impl, ok := parent.(Includable); ok { | ||
195 | include = impl | ||
196 | } | ||
197 | |||
198 | t := v.Type() | ||
199 | h, err := w.visit(reflect.ValueOf(t.Name()), nil) | ||
200 | if err != nil { | ||
201 | return 0, err | ||
202 | } | ||
203 | |||
204 | l := v.NumField() | ||
205 | for i := 0; i < l; i++ { | ||
206 | if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" { | ||
207 | var f visitFlag | ||
208 | fieldType := t.Field(i) | ||
209 | if fieldType.PkgPath != "" { | ||
210 | // Unexported | ||
211 | continue | ||
212 | } | ||
213 | |||
214 | tag := fieldType.Tag.Get(w.tag) | ||
215 | if tag == "ignore" { | ||
216 | // Ignore this field | ||
217 | continue | ||
218 | } | ||
219 | |||
220 | // Check if we implement includable and check it | ||
221 | if include != nil { | ||
222 | incl, err := include.HashInclude(fieldType.Name, v) | ||
223 | if err != nil { | ||
224 | return 0, err | ||
225 | } | ||
226 | if !incl { | ||
227 | continue | ||
228 | } | ||
229 | } | ||
230 | |||
231 | switch tag { | ||
232 | case "set": | ||
233 | f |= visitFlagSet | ||
234 | } | ||
235 | |||
236 | kh, err := w.visit(reflect.ValueOf(fieldType.Name), nil) | ||
237 | if err != nil { | ||
238 | return 0, err | ||
239 | } | ||
240 | |||
241 | vh, err := w.visit(v, &visitOpts{ | ||
242 | Flags: f, | ||
243 | Struct: parent, | ||
244 | StructField: fieldType.Name, | ||
245 | }) | ||
246 | if err != nil { | ||
247 | return 0, err | ||
248 | } | ||
249 | |||
250 | fieldHash := hashUpdateOrdered(w.h, kh, vh) | ||
251 | h = hashUpdateUnordered(h, fieldHash) | ||
252 | } | ||
253 | } | ||
254 | |||
255 | return h, nil | ||
256 | |||
257 | case reflect.Slice: | ||
258 | // We have two behaviors here. If it isn't a set, then we just | ||
259 | // visit all the elements. If it is a set, then we do a deterministic | ||
260 | // hash code. | ||
261 | var h uint64 | ||
262 | var set bool | ||
263 | if opts != nil { | ||
264 | set = (opts.Flags & visitFlagSet) != 0 | ||
265 | } | ||
266 | l := v.Len() | ||
267 | for i := 0; i < l; i++ { | ||
268 | current, err := w.visit(v.Index(i), nil) | ||
269 | if err != nil { | ||
270 | return 0, err | ||
271 | } | ||
272 | |||
273 | if set { | ||
274 | h = hashUpdateUnordered(h, current) | ||
275 | } else { | ||
276 | h = hashUpdateOrdered(w.h, h, current) | ||
277 | } | ||
278 | } | ||
279 | |||
280 | return h, nil | ||
281 | |||
282 | case reflect.String: | ||
283 | // Directly hash | ||
284 | w.h.Reset() | ||
285 | _, err := w.h.Write([]byte(v.String())) | ||
286 | return w.h.Sum64(), err | ||
287 | |||
288 | default: | ||
289 | return 0, fmt.Errorf("unknown kind to hash: %s", k) | ||
290 | } | ||
291 | |||
292 | return 0, nil | ||
293 | } | ||
294 | |||
295 | func hashUpdateOrdered(h hash.Hash64, a, b uint64) uint64 { | ||
296 | // For ordered updates, use a real hash function | ||
297 | h.Reset() | ||
298 | |||
299 | // We just panic if the binary writes fail because we are writing | ||
300 | // an int64 which should never be fail-able. | ||
301 | e1 := binary.Write(h, binary.LittleEndian, a) | ||
302 | e2 := binary.Write(h, binary.LittleEndian, b) | ||
303 | if e1 != nil { | ||
304 | panic(e1) | ||
305 | } | ||
306 | if e2 != nil { | ||
307 | panic(e2) | ||
308 | } | ||
309 | |||
310 | return h.Sum64() | ||
311 | } | ||
312 | |||
313 | func hashUpdateUnordered(a, b uint64) uint64 { | ||
314 | return a ^ b | ||
315 | } | ||
316 | |||
317 | // visitFlag is used as a bitmask for affecting visit behavior | ||
318 | type visitFlag uint | ||
319 | |||
320 | const ( | ||
321 | visitFlagInvalid visitFlag = iota | ||
322 | visitFlagSet = iota << 1 | ||
323 | ) | ||
diff --git a/vendor/github.com/mitchellh/hashstructure/include.go b/vendor/github.com/mitchellh/hashstructure/include.go new file mode 100644 index 0000000..b6289c0 --- /dev/null +++ b/vendor/github.com/mitchellh/hashstructure/include.go | |||
@@ -0,0 +1,15 @@ | |||
1 | package hashstructure | ||
2 | |||
3 | // Includable is an interface that can optionally be implemented by | ||
4 | // a struct. It will be called for each field in the struct to check whether | ||
5 | // it should be included in the hash. | ||
6 | type Includable interface { | ||
7 | HashInclude(field string, v interface{}) (bool, error) | ||
8 | } | ||
9 | |||
10 | // IncludableMap is an interface that can optionally be implemented by | ||
11 | // a struct. It will be called when a map-type field is found to ask the | ||
12 | // struct if the map item should be included in the hash. | ||
13 | type IncludableMap interface { | ||
14 | HashIncludeMap(field string, k, v interface{}) (bool, error) | ||
15 | } | ||
diff --git a/vendor/github.com/mitchellh/mapstructure/LICENSE b/vendor/github.com/mitchellh/mapstructure/LICENSE new file mode 100644 index 0000000..f9c841a --- /dev/null +++ b/vendor/github.com/mitchellh/mapstructure/LICENSE | |||
@@ -0,0 +1,21 @@ | |||
1 | The MIT License (MIT) | ||
2 | |||
3 | Copyright (c) 2013 Mitchell Hashimoto | ||
4 | |||
5 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
6 | of this software and associated documentation files (the "Software"), to deal | ||
7 | in the Software without restriction, including without limitation the rights | ||
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
9 | copies of the Software, and to permit persons to whom the Software is | ||
10 | furnished to do so, subject to the following conditions: | ||
11 | |||
12 | The above copyright notice and this permission notice shall be included in | ||
13 | all copies or substantial portions of the Software. | ||
14 | |||
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
21 | THE SOFTWARE. | ||
diff --git a/vendor/github.com/mitchellh/mapstructure/README.md b/vendor/github.com/mitchellh/mapstructure/README.md new file mode 100644 index 0000000..659d688 --- /dev/null +++ b/vendor/github.com/mitchellh/mapstructure/README.md | |||
@@ -0,0 +1,46 @@ | |||
1 | # mapstructure | ||
2 | |||
3 | mapstructure is a Go library for decoding generic map values to structures | ||
4 | and vice versa, while providing helpful error handling. | ||
5 | |||
6 | This library is most useful when decoding values from some data stream (JSON, | ||
7 | Gob, etc.) where you don't _quite_ know the structure of the underlying data | ||
8 | until you read a part of it. You can therefore read a `map[string]interface{}` | ||
9 | and use this library to decode it into the proper underlying native Go | ||
10 | structure. | ||
11 | |||
12 | ## Installation | ||
13 | |||
14 | Standard `go get`: | ||
15 | |||
16 | ``` | ||
17 | $ go get github.com/mitchellh/mapstructure | ||
18 | ``` | ||
19 | |||
20 | ## Usage & Example | ||
21 | |||
22 | For usage and examples see the [Godoc](http://godoc.org/github.com/mitchellh/mapstructure). | ||
23 | |||
24 | The `Decode` function has examples associated with it there. | ||
25 | |||
26 | ## But Why?! | ||
27 | |||
28 | Go offers fantastic standard libraries for decoding formats such as JSON. | ||
29 | The standard method is to have a struct pre-created, and populate that struct | ||
30 | from the bytes of the encoded format. This is great, but the problem is if | ||
31 | you have configuration or an encoding that changes slightly depending on | ||
32 | specific fields. For example, consider this JSON: | ||
33 | |||
34 | ```json | ||
35 | { | ||
36 | "type": "person", | ||
37 | "name": "Mitchell" | ||
38 | } | ||
39 | ``` | ||
40 | |||
41 | Perhaps we can't populate a specific structure without first reading | ||
42 | the "type" field from the JSON. We could always do two passes over the | ||
43 | decoding of the JSON (reading the "type" first, and the rest later). | ||
44 | However, it is much simpler to just decode this into a `map[string]interface{}` | ||
45 | structure, read the "type" key, then use something like this library | ||
46 | to decode it into the proper structure. | ||
diff --git a/vendor/github.com/mitchellh/mapstructure/decode_hooks.go b/vendor/github.com/mitchellh/mapstructure/decode_hooks.go new file mode 100644 index 0000000..115ae67 --- /dev/null +++ b/vendor/github.com/mitchellh/mapstructure/decode_hooks.go | |||
@@ -0,0 +1,154 @@ | |||
1 | package mapstructure | ||
2 | |||
3 | import ( | ||
4 | "errors" | ||
5 | "reflect" | ||
6 | "strconv" | ||
7 | "strings" | ||
8 | "time" | ||
9 | ) | ||
10 | |||
11 | // typedDecodeHook takes a raw DecodeHookFunc (an interface{}) and turns | ||
12 | // it into the proper DecodeHookFunc type, such as DecodeHookFuncType. | ||
13 | func typedDecodeHook(h DecodeHookFunc) DecodeHookFunc { | ||
14 | // Create variables here so we can reference them with the reflect pkg | ||
15 | var f1 DecodeHookFuncType | ||
16 | var f2 DecodeHookFuncKind | ||
17 | |||
18 | // Fill in the variables into this interface and the rest is done | ||
19 | // automatically using the reflect package. | ||
20 | potential := []interface{}{f1, f2} | ||
21 | |||
22 | v := reflect.ValueOf(h) | ||
23 | vt := v.Type() | ||
24 | for _, raw := range potential { | ||
25 | pt := reflect.ValueOf(raw).Type() | ||
26 | if vt.ConvertibleTo(pt) { | ||
27 | return v.Convert(pt).Interface() | ||
28 | } | ||
29 | } | ||
30 | |||
31 | return nil | ||
32 | } | ||
33 | |||
34 | // DecodeHookExec executes the given decode hook. This should be used | ||
35 | // since it'll naturally degrade to the older backwards compatible DecodeHookFunc | ||
36 | // that took reflect.Kind instead of reflect.Type. | ||
37 | func DecodeHookExec( | ||
38 | raw DecodeHookFunc, | ||
39 | from reflect.Type, to reflect.Type, | ||
40 | data interface{}) (interface{}, error) { | ||
41 | // Build our arguments that reflect expects | ||
42 | argVals := make([]reflect.Value, 3) | ||
43 | argVals[0] = reflect.ValueOf(from) | ||
44 | argVals[1] = reflect.ValueOf(to) | ||
45 | argVals[2] = reflect.ValueOf(data) | ||
46 | |||
47 | switch f := typedDecodeHook(raw).(type) { | ||
48 | case DecodeHookFuncType: | ||
49 | return f(from, to, data) | ||
50 | case DecodeHookFuncKind: | ||
51 | return f(from.Kind(), to.Kind(), data) | ||
52 | default: | ||
53 | return nil, errors.New("invalid decode hook signature") | ||
54 | } | ||
55 | } | ||
56 | |||
57 | // ComposeDecodeHookFunc creates a single DecodeHookFunc that | ||
58 | // automatically composes multiple DecodeHookFuncs. | ||
59 | // | ||
60 | // The composed funcs are called in order, with the result of the | ||
61 | // previous transformation. | ||
62 | func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc { | ||
63 | return func( | ||
64 | f reflect.Type, | ||
65 | t reflect.Type, | ||
66 | data interface{}) (interface{}, error) { | ||
67 | var err error | ||
68 | for _, f1 := range fs { | ||
69 | data, err = DecodeHookExec(f1, f, t, data) | ||
70 | if err != nil { | ||
71 | return nil, err | ||
72 | } | ||
73 | |||
74 | // Modify the from kind to be correct with the new data | ||
75 | f = nil | ||
76 | if val := reflect.ValueOf(data); val.IsValid() { | ||
77 | f = val.Type() | ||
78 | } | ||
79 | } | ||
80 | |||
81 | return data, nil | ||
82 | } | ||
83 | } | ||
84 | |||
85 | // StringToSliceHookFunc returns a DecodeHookFunc that converts | ||
86 | // string to []string by splitting on the given sep. | ||
87 | func StringToSliceHookFunc(sep string) DecodeHookFunc { | ||
88 | return func( | ||
89 | f reflect.Kind, | ||
90 | t reflect.Kind, | ||
91 | data interface{}) (interface{}, error) { | ||
92 | if f != reflect.String || t != reflect.Slice { | ||
93 | return data, nil | ||
94 | } | ||
95 | |||
96 | raw := data.(string) | ||
97 | if raw == "" { | ||
98 | return []string{}, nil | ||
99 | } | ||
100 | |||
101 | return strings.Split(raw, sep), nil | ||
102 | } | ||
103 | } | ||
104 | |||
105 | // StringToTimeDurationHookFunc returns a DecodeHookFunc that converts | ||
106 | // strings to time.Duration. | ||
107 | func StringToTimeDurationHookFunc() DecodeHookFunc { | ||
108 | return func( | ||
109 | f reflect.Type, | ||
110 | t reflect.Type, | ||
111 | data interface{}) (interface{}, error) { | ||
112 | if f.Kind() != reflect.String { | ||
113 | return data, nil | ||
114 | } | ||
115 | if t != reflect.TypeOf(time.Duration(5)) { | ||
116 | return data, nil | ||
117 | } | ||
118 | |||
119 | // Convert it by parsing | ||
120 | return time.ParseDuration(data.(string)) | ||
121 | } | ||
122 | } | ||
123 | |||
124 | func WeaklyTypedHook( | ||
125 | f reflect.Kind, | ||
126 | t reflect.Kind, | ||
127 | data interface{}) (interface{}, error) { | ||
128 | dataVal := reflect.ValueOf(data) | ||
129 | switch t { | ||
130 | case reflect.String: | ||
131 | switch f { | ||
132 | case reflect.Bool: | ||
133 | if dataVal.Bool() { | ||
134 | return "1", nil | ||
135 | } else { | ||
136 | return "0", nil | ||
137 | } | ||
138 | case reflect.Float32: | ||
139 | return strconv.FormatFloat(dataVal.Float(), 'f', -1, 64), nil | ||
140 | case reflect.Int: | ||
141 | return strconv.FormatInt(dataVal.Int(), 10), nil | ||
142 | case reflect.Slice: | ||
143 | dataType := dataVal.Type() | ||
144 | elemKind := dataType.Elem().Kind() | ||
145 | if elemKind == reflect.Uint8 { | ||
146 | return string(dataVal.Interface().([]uint8)), nil | ||
147 | } | ||
148 | case reflect.Uint: | ||
149 | return strconv.FormatUint(dataVal.Uint(), 10), nil | ||
150 | } | ||
151 | } | ||
152 | |||
153 | return data, nil | ||
154 | } | ||
diff --git a/vendor/github.com/mitchellh/mapstructure/error.go b/vendor/github.com/mitchellh/mapstructure/error.go new file mode 100644 index 0000000..47a99e5 --- /dev/null +++ b/vendor/github.com/mitchellh/mapstructure/error.go | |||
@@ -0,0 +1,50 @@ | |||
1 | package mapstructure | ||
2 | |||
3 | import ( | ||
4 | "errors" | ||
5 | "fmt" | ||
6 | "sort" | ||
7 | "strings" | ||
8 | ) | ||
9 | |||
10 | // Error implements the error interface and can represents multiple | ||
11 | // errors that occur in the course of a single decode. | ||
12 | type Error struct { | ||
13 | Errors []string | ||
14 | } | ||
15 | |||
16 | func (e *Error) Error() string { | ||
17 | points := make([]string, len(e.Errors)) | ||
18 | for i, err := range e.Errors { | ||
19 | points[i] = fmt.Sprintf("* %s", err) | ||
20 | } | ||
21 | |||
22 | sort.Strings(points) | ||
23 | return fmt.Sprintf( | ||
24 | "%d error(s) decoding:\n\n%s", | ||
25 | len(e.Errors), strings.Join(points, "\n")) | ||
26 | } | ||
27 | |||
28 | // WrappedErrors implements the errwrap.Wrapper interface to make this | ||
29 | // return value more useful with the errwrap and go-multierror libraries. | ||
30 | func (e *Error) WrappedErrors() []error { | ||
31 | if e == nil { | ||
32 | return nil | ||
33 | } | ||
34 | |||
35 | result := make([]error, len(e.Errors)) | ||
36 | for i, e := range e.Errors { | ||
37 | result[i] = errors.New(e) | ||
38 | } | ||
39 | |||
40 | return result | ||
41 | } | ||
42 | |||
43 | func appendErrors(errors []string, err error) []string { | ||
44 | switch e := err.(type) { | ||
45 | case *Error: | ||
46 | return append(errors, e.Errors...) | ||
47 | default: | ||
48 | return append(errors, e.Error()) | ||
49 | } | ||
50 | } | ||
diff --git a/vendor/github.com/mitchellh/mapstructure/mapstructure.go b/vendor/github.com/mitchellh/mapstructure/mapstructure.go new file mode 100644 index 0000000..6dee0ef --- /dev/null +++ b/vendor/github.com/mitchellh/mapstructure/mapstructure.go | |||
@@ -0,0 +1,823 @@ | |||
1 | // The mapstructure package exposes functionality to convert an | ||
2 | // arbitrary map[string]interface{} into a native Go structure. | ||
3 | // | ||
4 | // The Go structure can be arbitrarily complex, containing slices, | ||
5 | // other structs, etc. and the decoder will properly decode nested | ||
6 | // maps and so on into the proper structures in the native Go struct. | ||
7 | // See the examples to see what the decoder is capable of. | ||
8 | package mapstructure | ||
9 | |||
10 | import ( | ||
11 | "encoding/json" | ||
12 | "errors" | ||
13 | "fmt" | ||
14 | "reflect" | ||
15 | "sort" | ||
16 | "strconv" | ||
17 | "strings" | ||
18 | ) | ||
19 | |||
20 | // DecodeHookFunc is the callback function that can be used for | ||
21 | // data transformations. See "DecodeHook" in the DecoderConfig | ||
22 | // struct. | ||
23 | // | ||
24 | // The type should be DecodeHookFuncType or DecodeHookFuncKind. | ||
25 | // Either is accepted. Types are a superset of Kinds (Types can return | ||
26 | // Kinds) and are generally a richer thing to use, but Kinds are simpler | ||
27 | // if you only need those. | ||
28 | // | ||
29 | // The reason DecodeHookFunc is multi-typed is for backwards compatibility: | ||
30 | // we started with Kinds and then realized Types were the better solution, | ||
31 | // but have a promise to not break backwards compat so we now support | ||
32 | // both. | ||
33 | type DecodeHookFunc interface{} | ||
34 | |||
35 | type DecodeHookFuncType func(reflect.Type, reflect.Type, interface{}) (interface{}, error) | ||
36 | type DecodeHookFuncKind func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error) | ||
37 | |||
38 | // DecoderConfig is the configuration that is used to create a new decoder | ||
39 | // and allows customization of various aspects of decoding. | ||
40 | type DecoderConfig struct { | ||
41 | // DecodeHook, if set, will be called before any decoding and any | ||
42 | // type conversion (if WeaklyTypedInput is on). This lets you modify | ||
43 | // the values before they're set down onto the resulting struct. | ||
44 | // | ||
45 | // If an error is returned, the entire decode will fail with that | ||
46 | // error. | ||
47 | DecodeHook DecodeHookFunc | ||
48 | |||
49 | // If ErrorUnused is true, then it is an error for there to exist | ||
50 | // keys in the original map that were unused in the decoding process | ||
51 | // (extra keys). | ||
52 | ErrorUnused bool | ||
53 | |||
54 | // ZeroFields, if set to true, will zero fields before writing them. | ||
55 | // For example, a map will be emptied before decoded values are put in | ||
56 | // it. If this is false, a map will be merged. | ||
57 | ZeroFields bool | ||
58 | |||
59 | // If WeaklyTypedInput is true, the decoder will make the following | ||
60 | // "weak" conversions: | ||
61 | // | ||
62 | // - bools to string (true = "1", false = "0") | ||
63 | // - numbers to string (base 10) | ||
64 | // - bools to int/uint (true = 1, false = 0) | ||
65 | // - strings to int/uint (base implied by prefix) | ||
66 | // - int to bool (true if value != 0) | ||
67 | // - string to bool (accepts: 1, t, T, TRUE, true, True, 0, f, F, | ||
68 | // FALSE, false, False. Anything else is an error) | ||
69 | // - empty array = empty map and vice versa | ||
70 | // - negative numbers to overflowed uint values (base 10) | ||
71 | // - slice of maps to a merged map | ||
72 | // - single values are converted to slices if required. Each | ||
73 | // element is weakly decoded. For example: "4" can become []int{4} | ||
74 | // if the target type is an int slice. | ||
75 | // | ||
76 | WeaklyTypedInput bool | ||
77 | |||
78 | // Metadata is the struct that will contain extra metadata about | ||
79 | // the decoding. If this is nil, then no metadata will be tracked. | ||
80 | Metadata *Metadata | ||
81 | |||
82 | // Result is a pointer to the struct that will contain the decoded | ||
83 | // value. | ||
84 | Result interface{} | ||
85 | |||
86 | // The tag name that mapstructure reads for field names. This | ||
87 | // defaults to "mapstructure" | ||
88 | TagName string | ||
89 | } | ||
90 | |||
91 | // A Decoder takes a raw interface value and turns it into structured | ||
92 | // data, keeping track of rich error information along the way in case | ||
93 | // anything goes wrong. Unlike the basic top-level Decode method, you can | ||
94 | // more finely control how the Decoder behaves using the DecoderConfig | ||
95 | // structure. The top-level Decode method is just a convenience that sets | ||
96 | // up the most basic Decoder. | ||
97 | type Decoder struct { | ||
98 | config *DecoderConfig | ||
99 | } | ||
100 | |||
101 | // Metadata contains information about decoding a structure that | ||
102 | // is tedious or difficult to get otherwise. | ||
103 | type Metadata struct { | ||
104 | // Keys are the keys of the structure which were successfully decoded | ||
105 | Keys []string | ||
106 | |||
107 | // Unused is a slice of keys that were found in the raw value but | ||
108 | // weren't decoded since there was no matching field in the result interface | ||
109 | Unused []string | ||
110 | } | ||
111 | |||
112 | // Decode takes a map and uses reflection to convert it into the | ||
113 | // given Go native structure. val must be a pointer to a struct. | ||
114 | func Decode(m interface{}, rawVal interface{}) error { | ||
115 | config := &DecoderConfig{ | ||
116 | Metadata: nil, | ||
117 | Result: rawVal, | ||
118 | } | ||
119 | |||
120 | decoder, err := NewDecoder(config) | ||
121 | if err != nil { | ||
122 | return err | ||
123 | } | ||
124 | |||
125 | return decoder.Decode(m) | ||
126 | } | ||
127 | |||
128 | // WeakDecode is the same as Decode but is shorthand to enable | ||
129 | // WeaklyTypedInput. See DecoderConfig for more info. | ||
130 | func WeakDecode(input, output interface{}) error { | ||
131 | config := &DecoderConfig{ | ||
132 | Metadata: nil, | ||
133 | Result: output, | ||
134 | WeaklyTypedInput: true, | ||
135 | } | ||
136 | |||
137 | decoder, err := NewDecoder(config) | ||
138 | if err != nil { | ||
139 | return err | ||
140 | } | ||
141 | |||
142 | return decoder.Decode(input) | ||
143 | } | ||
144 | |||
145 | // NewDecoder returns a new decoder for the given configuration. Once | ||
146 | // a decoder has been returned, the same configuration must not be used | ||
147 | // again. | ||
148 | func NewDecoder(config *DecoderConfig) (*Decoder, error) { | ||
149 | val := reflect.ValueOf(config.Result) | ||
150 | if val.Kind() != reflect.Ptr { | ||
151 | return nil, errors.New("result must be a pointer") | ||
152 | } | ||
153 | |||
154 | val = val.Elem() | ||
155 | if !val.CanAddr() { | ||
156 | return nil, errors.New("result must be addressable (a pointer)") | ||
157 | } | ||
158 | |||
159 | if config.Metadata != nil { | ||
160 | if config.Metadata.Keys == nil { | ||
161 | config.Metadata.Keys = make([]string, 0) | ||
162 | } | ||
163 | |||
164 | if config.Metadata.Unused == nil { | ||
165 | config.Metadata.Unused = make([]string, 0) | ||
166 | } | ||
167 | } | ||
168 | |||
169 | if config.TagName == "" { | ||
170 | config.TagName = "mapstructure" | ||
171 | } | ||
172 | |||
173 | result := &Decoder{ | ||
174 | config: config, | ||
175 | } | ||
176 | |||
177 | return result, nil | ||
178 | } | ||
179 | |||
180 | // Decode decodes the given raw interface to the target pointer specified | ||
181 | // by the configuration. | ||
182 | func (d *Decoder) Decode(raw interface{}) error { | ||
183 | return d.decode("", raw, reflect.ValueOf(d.config.Result).Elem()) | ||
184 | } | ||
185 | |||
186 | // Decodes an unknown data type into a specific reflection value. | ||
187 | func (d *Decoder) decode(name string, data interface{}, val reflect.Value) error { | ||
188 | if data == nil { | ||
189 | // If the data is nil, then we don't set anything. | ||
190 | return nil | ||
191 | } | ||
192 | |||
193 | dataVal := reflect.ValueOf(data) | ||
194 | if !dataVal.IsValid() { | ||
195 | // If the data value is invalid, then we just set the value | ||
196 | // to be the zero value. | ||
197 | val.Set(reflect.Zero(val.Type())) | ||
198 | return nil | ||
199 | } | ||
200 | |||
201 | if d.config.DecodeHook != nil { | ||
202 | // We have a DecodeHook, so let's pre-process the data. | ||
203 | var err error | ||
204 | data, err = DecodeHookExec( | ||
205 | d.config.DecodeHook, | ||
206 | dataVal.Type(), val.Type(), data) | ||
207 | if err != nil { | ||
208 | return fmt.Errorf("error decoding '%s': %s", name, err) | ||
209 | } | ||
210 | } | ||
211 | |||
212 | var err error | ||
213 | dataKind := getKind(val) | ||
214 | switch dataKind { | ||
215 | case reflect.Bool: | ||
216 | err = d.decodeBool(name, data, val) | ||
217 | case reflect.Interface: | ||
218 | err = d.decodeBasic(name, data, val) | ||
219 | case reflect.String: | ||
220 | err = d.decodeString(name, data, val) | ||
221 | case reflect.Int: | ||
222 | err = d.decodeInt(name, data, val) | ||
223 | case reflect.Uint: | ||
224 | err = d.decodeUint(name, data, val) | ||
225 | case reflect.Float32: | ||
226 | err = d.decodeFloat(name, data, val) | ||
227 | case reflect.Struct: | ||
228 | err = d.decodeStruct(name, data, val) | ||
229 | case reflect.Map: | ||
230 | err = d.decodeMap(name, data, val) | ||
231 | case reflect.Ptr: | ||
232 | err = d.decodePtr(name, data, val) | ||
233 | case reflect.Slice: | ||
234 | err = d.decodeSlice(name, data, val) | ||
235 | case reflect.Func: | ||
236 | err = d.decodeFunc(name, data, val) | ||
237 | default: | ||
238 | // If we reached this point then we weren't able to decode it | ||
239 | return fmt.Errorf("%s: unsupported type: %s", name, dataKind) | ||
240 | } | ||
241 | |||
242 | // If we reached here, then we successfully decoded SOMETHING, so | ||
243 | // mark the key as used if we're tracking metadata. | ||
244 | if d.config.Metadata != nil && name != "" { | ||
245 | d.config.Metadata.Keys = append(d.config.Metadata.Keys, name) | ||
246 | } | ||
247 | |||
248 | return err | ||
249 | } | ||
250 | |||
251 | // This decodes a basic type (bool, int, string, etc.) and sets the | ||
252 | // value to "data" of that type. | ||
253 | func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error { | ||
254 | dataVal := reflect.ValueOf(data) | ||
255 | if !dataVal.IsValid() { | ||
256 | dataVal = reflect.Zero(val.Type()) | ||
257 | } | ||
258 | |||
259 | dataValType := dataVal.Type() | ||
260 | if !dataValType.AssignableTo(val.Type()) { | ||
261 | return fmt.Errorf( | ||
262 | "'%s' expected type '%s', got '%s'", | ||
263 | name, val.Type(), dataValType) | ||
264 | } | ||
265 | |||
266 | val.Set(dataVal) | ||
267 | return nil | ||
268 | } | ||
269 | |||
270 | func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) error { | ||
271 | dataVal := reflect.ValueOf(data) | ||
272 | dataKind := getKind(dataVal) | ||
273 | |||
274 | converted := true | ||
275 | switch { | ||
276 | case dataKind == reflect.String: | ||
277 | val.SetString(dataVal.String()) | ||
278 | case dataKind == reflect.Bool && d.config.WeaklyTypedInput: | ||
279 | if dataVal.Bool() { | ||
280 | val.SetString("1") | ||
281 | } else { | ||
282 | val.SetString("0") | ||
283 | } | ||
284 | case dataKind == reflect.Int && d.config.WeaklyTypedInput: | ||
285 | val.SetString(strconv.FormatInt(dataVal.Int(), 10)) | ||
286 | case dataKind == reflect.Uint && d.config.WeaklyTypedInput: | ||
287 | val.SetString(strconv.FormatUint(dataVal.Uint(), 10)) | ||
288 | case dataKind == reflect.Float32 && d.config.WeaklyTypedInput: | ||
289 | val.SetString(strconv.FormatFloat(dataVal.Float(), 'f', -1, 64)) | ||
290 | case dataKind == reflect.Slice && d.config.WeaklyTypedInput: | ||
291 | dataType := dataVal.Type() | ||
292 | elemKind := dataType.Elem().Kind() | ||
293 | switch { | ||
294 | case elemKind == reflect.Uint8: | ||
295 | val.SetString(string(dataVal.Interface().([]uint8))) | ||
296 | default: | ||
297 | converted = false | ||
298 | } | ||
299 | default: | ||
300 | converted = false | ||
301 | } | ||
302 | |||
303 | if !converted { | ||
304 | return fmt.Errorf( | ||
305 | "'%s' expected type '%s', got unconvertible type '%s'", | ||
306 | name, val.Type(), dataVal.Type()) | ||
307 | } | ||
308 | |||
309 | return nil | ||
310 | } | ||
311 | |||
312 | func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) error { | ||
313 | dataVal := reflect.ValueOf(data) | ||
314 | dataKind := getKind(dataVal) | ||
315 | dataType := dataVal.Type() | ||
316 | |||
317 | switch { | ||
318 | case dataKind == reflect.Int: | ||
319 | val.SetInt(dataVal.Int()) | ||
320 | case dataKind == reflect.Uint: | ||
321 | val.SetInt(int64(dataVal.Uint())) | ||
322 | case dataKind == reflect.Float32: | ||
323 | val.SetInt(int64(dataVal.Float())) | ||
324 | case dataKind == reflect.Bool && d.config.WeaklyTypedInput: | ||
325 | if dataVal.Bool() { | ||
326 | val.SetInt(1) | ||
327 | } else { | ||
328 | val.SetInt(0) | ||
329 | } | ||
330 | case dataKind == reflect.String && d.config.WeaklyTypedInput: | ||
331 | i, err := strconv.ParseInt(dataVal.String(), 0, val.Type().Bits()) | ||
332 | if err == nil { | ||
333 | val.SetInt(i) | ||
334 | } else { | ||
335 | return fmt.Errorf("cannot parse '%s' as int: %s", name, err) | ||
336 | } | ||
337 | case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number": | ||
338 | jn := data.(json.Number) | ||
339 | i, err := jn.Int64() | ||
340 | if err != nil { | ||
341 | return fmt.Errorf( | ||
342 | "error decoding json.Number into %s: %s", name, err) | ||
343 | } | ||
344 | val.SetInt(i) | ||
345 | default: | ||
346 | return fmt.Errorf( | ||
347 | "'%s' expected type '%s', got unconvertible type '%s'", | ||
348 | name, val.Type(), dataVal.Type()) | ||
349 | } | ||
350 | |||
351 | return nil | ||
352 | } | ||
353 | |||
354 | func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) error { | ||
355 | dataVal := reflect.ValueOf(data) | ||
356 | dataKind := getKind(dataVal) | ||
357 | |||
358 | switch { | ||
359 | case dataKind == reflect.Int: | ||
360 | i := dataVal.Int() | ||
361 | if i < 0 && !d.config.WeaklyTypedInput { | ||
362 | return fmt.Errorf("cannot parse '%s', %d overflows uint", | ||
363 | name, i) | ||
364 | } | ||
365 | val.SetUint(uint64(i)) | ||
366 | case dataKind == reflect.Uint: | ||
367 | val.SetUint(dataVal.Uint()) | ||
368 | case dataKind == reflect.Float32: | ||
369 | f := dataVal.Float() | ||
370 | if f < 0 && !d.config.WeaklyTypedInput { | ||
371 | return fmt.Errorf("cannot parse '%s', %f overflows uint", | ||
372 | name, f) | ||
373 | } | ||
374 | val.SetUint(uint64(f)) | ||
375 | case dataKind == reflect.Bool && d.config.WeaklyTypedInput: | ||
376 | if dataVal.Bool() { | ||
377 | val.SetUint(1) | ||
378 | } else { | ||
379 | val.SetUint(0) | ||
380 | } | ||
381 | case dataKind == reflect.String && d.config.WeaklyTypedInput: | ||
382 | i, err := strconv.ParseUint(dataVal.String(), 0, val.Type().Bits()) | ||
383 | if err == nil { | ||
384 | val.SetUint(i) | ||
385 | } else { | ||
386 | return fmt.Errorf("cannot parse '%s' as uint: %s", name, err) | ||
387 | } | ||
388 | default: | ||
389 | return fmt.Errorf( | ||
390 | "'%s' expected type '%s', got unconvertible type '%s'", | ||
391 | name, val.Type(), dataVal.Type()) | ||
392 | } | ||
393 | |||
394 | return nil | ||
395 | } | ||
396 | |||
397 | func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) error { | ||
398 | dataVal := reflect.ValueOf(data) | ||
399 | dataKind := getKind(dataVal) | ||
400 | |||
401 | switch { | ||
402 | case dataKind == reflect.Bool: | ||
403 | val.SetBool(dataVal.Bool()) | ||
404 | case dataKind == reflect.Int && d.config.WeaklyTypedInput: | ||
405 | val.SetBool(dataVal.Int() != 0) | ||
406 | case dataKind == reflect.Uint && d.config.WeaklyTypedInput: | ||
407 | val.SetBool(dataVal.Uint() != 0) | ||
408 | case dataKind == reflect.Float32 && d.config.WeaklyTypedInput: | ||
409 | val.SetBool(dataVal.Float() != 0) | ||
410 | case dataKind == reflect.String && d.config.WeaklyTypedInput: | ||
411 | b, err := strconv.ParseBool(dataVal.String()) | ||
412 | if err == nil { | ||
413 | val.SetBool(b) | ||
414 | } else if dataVal.String() == "" { | ||
415 | val.SetBool(false) | ||
416 | } else { | ||
417 | return fmt.Errorf("cannot parse '%s' as bool: %s", name, err) | ||
418 | } | ||
419 | default: | ||
420 | return fmt.Errorf( | ||
421 | "'%s' expected type '%s', got unconvertible type '%s'", | ||
422 | name, val.Type(), dataVal.Type()) | ||
423 | } | ||
424 | |||
425 | return nil | ||
426 | } | ||
427 | |||
428 | func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) error { | ||
429 | dataVal := reflect.ValueOf(data) | ||
430 | dataKind := getKind(dataVal) | ||
431 | dataType := dataVal.Type() | ||
432 | |||
433 | switch { | ||
434 | case dataKind == reflect.Int: | ||
435 | val.SetFloat(float64(dataVal.Int())) | ||
436 | case dataKind == reflect.Uint: | ||
437 | val.SetFloat(float64(dataVal.Uint())) | ||
438 | case dataKind == reflect.Float32: | ||
439 | val.SetFloat(float64(dataVal.Float())) | ||
440 | case dataKind == reflect.Bool && d.config.WeaklyTypedInput: | ||
441 | if dataVal.Bool() { | ||
442 | val.SetFloat(1) | ||
443 | } else { | ||
444 | val.SetFloat(0) | ||
445 | } | ||
446 | case dataKind == reflect.String && d.config.WeaklyTypedInput: | ||
447 | f, err := strconv.ParseFloat(dataVal.String(), val.Type().Bits()) | ||
448 | if err == nil { | ||
449 | val.SetFloat(f) | ||
450 | } else { | ||
451 | return fmt.Errorf("cannot parse '%s' as float: %s", name, err) | ||
452 | } | ||
453 | case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number": | ||
454 | jn := data.(json.Number) | ||
455 | i, err := jn.Float64() | ||
456 | if err != nil { | ||
457 | return fmt.Errorf( | ||
458 | "error decoding json.Number into %s: %s", name, err) | ||
459 | } | ||
460 | val.SetFloat(i) | ||
461 | default: | ||
462 | return fmt.Errorf( | ||
463 | "'%s' expected type '%s', got unconvertible type '%s'", | ||
464 | name, val.Type(), dataVal.Type()) | ||
465 | } | ||
466 | |||
467 | return nil | ||
468 | } | ||
469 | |||
470 | func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) error { | ||
471 | valType := val.Type() | ||
472 | valKeyType := valType.Key() | ||
473 | valElemType := valType.Elem() | ||
474 | |||
475 | // By default we overwrite keys in the current map | ||
476 | valMap := val | ||
477 | |||
478 | // If the map is nil or we're purposely zeroing fields, make a new map | ||
479 | if valMap.IsNil() || d.config.ZeroFields { | ||
480 | // Make a new map to hold our result | ||
481 | mapType := reflect.MapOf(valKeyType, valElemType) | ||
482 | valMap = reflect.MakeMap(mapType) | ||
483 | } | ||
484 | |||
485 | // Check input type | ||
486 | dataVal := reflect.Indirect(reflect.ValueOf(data)) | ||
487 | if dataVal.Kind() != reflect.Map { | ||
488 | // In weak mode, we accept a slice of maps as an input... | ||
489 | if d.config.WeaklyTypedInput { | ||
490 | switch dataVal.Kind() { | ||
491 | case reflect.Array, reflect.Slice: | ||
492 | // Special case for BC reasons (covered by tests) | ||
493 | if dataVal.Len() == 0 { | ||
494 | val.Set(valMap) | ||
495 | return nil | ||
496 | } | ||
497 | |||
498 | for i := 0; i < dataVal.Len(); i++ { | ||
499 | err := d.decode( | ||
500 | fmt.Sprintf("%s[%d]", name, i), | ||
501 | dataVal.Index(i).Interface(), val) | ||
502 | if err != nil { | ||
503 | return err | ||
504 | } | ||
505 | } | ||
506 | |||
507 | return nil | ||
508 | } | ||
509 | } | ||
510 | |||
511 | return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind()) | ||
512 | } | ||
513 | |||
514 | // Accumulate errors | ||
515 | errors := make([]string, 0) | ||
516 | |||
517 | for _, k := range dataVal.MapKeys() { | ||
518 | fieldName := fmt.Sprintf("%s[%s]", name, k) | ||
519 | |||
520 | // First decode the key into the proper type | ||
521 | currentKey := reflect.Indirect(reflect.New(valKeyType)) | ||
522 | if err := d.decode(fieldName, k.Interface(), currentKey); err != nil { | ||
523 | errors = appendErrors(errors, err) | ||
524 | continue | ||
525 | } | ||
526 | |||
527 | // Next decode the data into the proper type | ||
528 | v := dataVal.MapIndex(k).Interface() | ||
529 | currentVal := reflect.Indirect(reflect.New(valElemType)) | ||
530 | if err := d.decode(fieldName, v, currentVal); err != nil { | ||
531 | errors = appendErrors(errors, err) | ||
532 | continue | ||
533 | } | ||
534 | |||
535 | valMap.SetMapIndex(currentKey, currentVal) | ||
536 | } | ||
537 | |||
538 | // Set the built up map to the value | ||
539 | val.Set(valMap) | ||
540 | |||
541 | // If we had errors, return those | ||
542 | if len(errors) > 0 { | ||
543 | return &Error{errors} | ||
544 | } | ||
545 | |||
546 | return nil | ||
547 | } | ||
548 | |||
549 | func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) error { | ||
550 | // Create an element of the concrete (non pointer) type and decode | ||
551 | // into that. Then set the value of the pointer to this type. | ||
552 | valType := val.Type() | ||
553 | valElemType := valType.Elem() | ||
554 | |||
555 | realVal := val | ||
556 | if realVal.IsNil() || d.config.ZeroFields { | ||
557 | realVal = reflect.New(valElemType) | ||
558 | } | ||
559 | |||
560 | if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil { | ||
561 | return err | ||
562 | } | ||
563 | |||
564 | val.Set(realVal) | ||
565 | return nil | ||
566 | } | ||
567 | |||
568 | func (d *Decoder) decodeFunc(name string, data interface{}, val reflect.Value) error { | ||
569 | // Create an element of the concrete (non pointer) type and decode | ||
570 | // into that. Then set the value of the pointer to this type. | ||
571 | dataVal := reflect.Indirect(reflect.ValueOf(data)) | ||
572 | if val.Type() != dataVal.Type() { | ||
573 | return fmt.Errorf( | ||
574 | "'%s' expected type '%s', got unconvertible type '%s'", | ||
575 | name, val.Type(), dataVal.Type()) | ||
576 | } | ||
577 | val.Set(dataVal) | ||
578 | return nil | ||
579 | } | ||
580 | |||
581 | func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error { | ||
582 | dataVal := reflect.Indirect(reflect.ValueOf(data)) | ||
583 | dataValKind := dataVal.Kind() | ||
584 | valType := val.Type() | ||
585 | valElemType := valType.Elem() | ||
586 | sliceType := reflect.SliceOf(valElemType) | ||
587 | |||
588 | valSlice := val | ||
589 | if valSlice.IsNil() || d.config.ZeroFields { | ||
590 | // Check input type | ||
591 | if dataValKind != reflect.Array && dataValKind != reflect.Slice { | ||
592 | if d.config.WeaklyTypedInput { | ||
593 | switch { | ||
594 | // Empty maps turn into empty slices | ||
595 | case dataValKind == reflect.Map: | ||
596 | if dataVal.Len() == 0 { | ||
597 | val.Set(reflect.MakeSlice(sliceType, 0, 0)) | ||
598 | return nil | ||
599 | } | ||
600 | |||
601 | // All other types we try to convert to the slice type | ||
602 | // and "lift" it into it. i.e. a string becomes a string slice. | ||
603 | default: | ||
604 | // Just re-try this function with data as a slice. | ||
605 | return d.decodeSlice(name, []interface{}{data}, val) | ||
606 | } | ||
607 | } | ||
608 | |||
609 | return fmt.Errorf( | ||
610 | "'%s': source data must be an array or slice, got %s", name, dataValKind) | ||
611 | |||
612 | } | ||
613 | |||
614 | // Make a new slice to hold our result, same size as the original data. | ||
615 | valSlice = reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len()) | ||
616 | } | ||
617 | |||
618 | // Accumulate any errors | ||
619 | errors := make([]string, 0) | ||
620 | |||
621 | for i := 0; i < dataVal.Len(); i++ { | ||
622 | currentData := dataVal.Index(i).Interface() | ||
623 | for valSlice.Len() <= i { | ||
624 | valSlice = reflect.Append(valSlice, reflect.Zero(valElemType)) | ||
625 | } | ||
626 | currentField := valSlice.Index(i) | ||
627 | |||
628 | fieldName := fmt.Sprintf("%s[%d]", name, i) | ||
629 | if err := d.decode(fieldName, currentData, currentField); err != nil { | ||
630 | errors = appendErrors(errors, err) | ||
631 | } | ||
632 | } | ||
633 | |||
634 | // Finally, set the value to the slice we built up | ||
635 | val.Set(valSlice) | ||
636 | |||
637 | // If there were errors, we return those | ||
638 | if len(errors) > 0 { | ||
639 | return &Error{errors} | ||
640 | } | ||
641 | |||
642 | return nil | ||
643 | } | ||
644 | |||
645 | func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) error { | ||
646 | dataVal := reflect.Indirect(reflect.ValueOf(data)) | ||
647 | |||
648 | // If the type of the value to write to and the data match directly, | ||
649 | // then we just set it directly instead of recursing into the structure. | ||
650 | if dataVal.Type() == val.Type() { | ||
651 | val.Set(dataVal) | ||
652 | return nil | ||
653 | } | ||
654 | |||
655 | dataValKind := dataVal.Kind() | ||
656 | if dataValKind != reflect.Map { | ||
657 | return fmt.Errorf("'%s' expected a map, got '%s'", name, dataValKind) | ||
658 | } | ||
659 | |||
660 | dataValType := dataVal.Type() | ||
661 | if kind := dataValType.Key().Kind(); kind != reflect.String && kind != reflect.Interface { | ||
662 | return fmt.Errorf( | ||
663 | "'%s' needs a map with string keys, has '%s' keys", | ||
664 | name, dataValType.Key().Kind()) | ||
665 | } | ||
666 | |||
667 | dataValKeys := make(map[reflect.Value]struct{}) | ||
668 | dataValKeysUnused := make(map[interface{}]struct{}) | ||
669 | for _, dataValKey := range dataVal.MapKeys() { | ||
670 | dataValKeys[dataValKey] = struct{}{} | ||
671 | dataValKeysUnused[dataValKey.Interface()] = struct{}{} | ||
672 | } | ||
673 | |||
674 | errors := make([]string, 0) | ||
675 | |||
676 | // This slice will keep track of all the structs we'll be decoding. | ||
677 | // There can be more than one struct if there are embedded structs | ||
678 | // that are squashed. | ||
679 | structs := make([]reflect.Value, 1, 5) | ||
680 | structs[0] = val | ||
681 | |||
682 | // Compile the list of all the fields that we're going to be decoding | ||
683 | // from all the structs. | ||
684 | fields := make(map[*reflect.StructField]reflect.Value) | ||
685 | for len(structs) > 0 { | ||
686 | structVal := structs[0] | ||
687 | structs = structs[1:] | ||
688 | |||
689 | structType := structVal.Type() | ||
690 | |||
691 | for i := 0; i < structType.NumField(); i++ { | ||
692 | fieldType := structType.Field(i) | ||
693 | fieldKind := fieldType.Type.Kind() | ||
694 | |||
695 | // If "squash" is specified in the tag, we squash the field down. | ||
696 | squash := false | ||
697 | tagParts := strings.Split(fieldType.Tag.Get(d.config.TagName), ",") | ||
698 | for _, tag := range tagParts[1:] { | ||
699 | if tag == "squash" { | ||
700 | squash = true | ||
701 | break | ||
702 | } | ||
703 | } | ||
704 | |||
705 | if squash { | ||
706 | if fieldKind != reflect.Struct { | ||
707 | errors = appendErrors(errors, | ||
708 | fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldKind)) | ||
709 | } else { | ||
710 | structs = append(structs, val.FieldByName(fieldType.Name)) | ||
711 | } | ||
712 | continue | ||
713 | } | ||
714 | |||
715 | // Normal struct field, store it away | ||
716 | fields[&fieldType] = structVal.Field(i) | ||
717 | } | ||
718 | } | ||
719 | |||
720 | for fieldType, field := range fields { | ||
721 | fieldName := fieldType.Name | ||
722 | |||
723 | tagValue := fieldType.Tag.Get(d.config.TagName) | ||
724 | tagValue = strings.SplitN(tagValue, ",", 2)[0] | ||
725 | if tagValue != "" { | ||
726 | fieldName = tagValue | ||
727 | } | ||
728 | |||
729 | rawMapKey := reflect.ValueOf(fieldName) | ||
730 | rawMapVal := dataVal.MapIndex(rawMapKey) | ||
731 | if !rawMapVal.IsValid() { | ||
732 | // Do a slower search by iterating over each key and | ||
733 | // doing case-insensitive search. | ||
734 | for dataValKey := range dataValKeys { | ||
735 | mK, ok := dataValKey.Interface().(string) | ||
736 | if !ok { | ||
737 | // Not a string key | ||
738 | continue | ||
739 | } | ||
740 | |||
741 | if strings.EqualFold(mK, fieldName) { | ||
742 | rawMapKey = dataValKey | ||
743 | rawMapVal = dataVal.MapIndex(dataValKey) | ||
744 | break | ||
745 | } | ||
746 | } | ||
747 | |||
748 | if !rawMapVal.IsValid() { | ||
749 | // There was no matching key in the map for the value in | ||
750 | // the struct. Just ignore. | ||
751 | continue | ||
752 | } | ||
753 | } | ||
754 | |||
755 | // Delete the key we're using from the unused map so we stop tracking | ||
756 | delete(dataValKeysUnused, rawMapKey.Interface()) | ||
757 | |||
758 | if !field.IsValid() { | ||
759 | // This should never happen | ||
760 | panic("field is not valid") | ||
761 | } | ||
762 | |||
763 | // If we can't set the field, then it is unexported or something, | ||
764 | // and we just continue onwards. | ||
765 | if !field.CanSet() { | ||
766 | continue | ||
767 | } | ||
768 | |||
769 | // If the name is empty string, then we're at the root, and we | ||
770 | // don't dot-join the fields. | ||
771 | if name != "" { | ||
772 | fieldName = fmt.Sprintf("%s.%s", name, fieldName) | ||
773 | } | ||
774 | |||
775 | if err := d.decode(fieldName, rawMapVal.Interface(), field); err != nil { | ||
776 | errors = appendErrors(errors, err) | ||
777 | } | ||
778 | } | ||
779 | |||
780 | if d.config.ErrorUnused && len(dataValKeysUnused) > 0 { | ||
781 | keys := make([]string, 0, len(dataValKeysUnused)) | ||
782 | for rawKey := range dataValKeysUnused { | ||
783 | keys = append(keys, rawKey.(string)) | ||
784 | } | ||
785 | sort.Strings(keys) | ||
786 | |||
787 | err := fmt.Errorf("'%s' has invalid keys: %s", name, strings.Join(keys, ", ")) | ||
788 | errors = appendErrors(errors, err) | ||
789 | } | ||
790 | |||
791 | if len(errors) > 0 { | ||
792 | return &Error{errors} | ||
793 | } | ||
794 | |||
795 | // Add the unused keys to the list of unused keys if we're tracking metadata | ||
796 | if d.config.Metadata != nil { | ||
797 | for rawKey := range dataValKeysUnused { | ||
798 | key := rawKey.(string) | ||
799 | if name != "" { | ||
800 | key = fmt.Sprintf("%s.%s", name, key) | ||
801 | } | ||
802 | |||
803 | d.config.Metadata.Unused = append(d.config.Metadata.Unused, key) | ||
804 | } | ||
805 | } | ||
806 | |||
807 | return nil | ||
808 | } | ||
809 | |||
810 | func getKind(val reflect.Value) reflect.Kind { | ||
811 | kind := val.Kind() | ||
812 | |||
813 | switch { | ||
814 | case kind >= reflect.Int && kind <= reflect.Int64: | ||
815 | return reflect.Int | ||
816 | case kind >= reflect.Uint && kind <= reflect.Uint64: | ||
817 | return reflect.Uint | ||
818 | case kind >= reflect.Float32 && kind <= reflect.Float64: | ||
819 | return reflect.Float32 | ||
820 | default: | ||
821 | return kind | ||
822 | } | ||
823 | } | ||
diff --git a/vendor/github.com/mitchellh/reflectwalk/LICENSE b/vendor/github.com/mitchellh/reflectwalk/LICENSE new file mode 100644 index 0000000..f9c841a --- /dev/null +++ b/vendor/github.com/mitchellh/reflectwalk/LICENSE | |||
@@ -0,0 +1,21 @@ | |||
1 | The MIT License (MIT) | ||
2 | |||
3 | Copyright (c) 2013 Mitchell Hashimoto | ||
4 | |||
5 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
6 | of this software and associated documentation files (the "Software"), to deal | ||
7 | in the Software without restriction, including without limitation the rights | ||
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
9 | copies of the Software, and to permit persons to whom the Software is | ||
10 | furnished to do so, subject to the following conditions: | ||
11 | |||
12 | The above copyright notice and this permission notice shall be included in | ||
13 | all copies or substantial portions of the Software. | ||
14 | |||
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
21 | THE SOFTWARE. | ||
diff --git a/vendor/github.com/mitchellh/reflectwalk/README.md b/vendor/github.com/mitchellh/reflectwalk/README.md new file mode 100644 index 0000000..ac82cd2 --- /dev/null +++ b/vendor/github.com/mitchellh/reflectwalk/README.md | |||
@@ -0,0 +1,6 @@ | |||
1 | # reflectwalk | ||
2 | |||
3 | reflectwalk is a Go library for "walking" a value in Go using reflection, | ||
4 | in the same way a directory tree can be "walked" on the filesystem. Walking | ||
5 | a complex structure can allow you to do manipulations on unknown structures | ||
6 | such as those decoded from JSON. | ||
diff --git a/vendor/github.com/mitchellh/reflectwalk/location.go b/vendor/github.com/mitchellh/reflectwalk/location.go new file mode 100644 index 0000000..7c59d76 --- /dev/null +++ b/vendor/github.com/mitchellh/reflectwalk/location.go | |||
@@ -0,0 +1,17 @@ | |||
1 | package reflectwalk | ||
2 | |||
3 | //go:generate stringer -type=Location location.go | ||
4 | |||
5 | type Location uint | ||
6 | |||
7 | const ( | ||
8 | None Location = iota | ||
9 | Map | ||
10 | MapKey | ||
11 | MapValue | ||
12 | Slice | ||
13 | SliceElem | ||
14 | Struct | ||
15 | StructField | ||
16 | WalkLoc | ||
17 | ) | ||
diff --git a/vendor/github.com/mitchellh/reflectwalk/location_string.go b/vendor/github.com/mitchellh/reflectwalk/location_string.go new file mode 100644 index 0000000..d3cfe85 --- /dev/null +++ b/vendor/github.com/mitchellh/reflectwalk/location_string.go | |||
@@ -0,0 +1,16 @@ | |||
1 | // generated by stringer -type=Location location.go; DO NOT EDIT | ||
2 | |||
3 | package reflectwalk | ||
4 | |||
5 | import "fmt" | ||
6 | |||
7 | const _Location_name = "NoneMapMapKeyMapValueSliceSliceElemStructStructFieldWalkLoc" | ||
8 | |||
9 | var _Location_index = [...]uint8{0, 4, 7, 13, 21, 26, 35, 41, 52, 59} | ||
10 | |||
11 | func (i Location) String() string { | ||
12 | if i+1 >= Location(len(_Location_index)) { | ||
13 | return fmt.Sprintf("Location(%d)", i) | ||
14 | } | ||
15 | return _Location_name[_Location_index[i]:_Location_index[i+1]] | ||
16 | } | ||
diff --git a/vendor/github.com/mitchellh/reflectwalk/reflectwalk.go b/vendor/github.com/mitchellh/reflectwalk/reflectwalk.go new file mode 100644 index 0000000..ec0a623 --- /dev/null +++ b/vendor/github.com/mitchellh/reflectwalk/reflectwalk.go | |||
@@ -0,0 +1,339 @@ | |||
1 | // reflectwalk is a package that allows you to "walk" complex structures | ||
2 | // similar to how you may "walk" a filesystem: visiting every element one | ||
3 | // by one and calling callback functions allowing you to handle and manipulate | ||
4 | // those elements. | ||
5 | package reflectwalk | ||
6 | |||
7 | import ( | ||
8 | "errors" | ||
9 | "reflect" | ||
10 | ) | ||
11 | |||
12 | // PrimitiveWalker implementations are able to handle primitive values | ||
13 | // within complex structures. Primitive values are numbers, strings, | ||
14 | // booleans, funcs, chans. | ||
15 | // | ||
16 | // These primitive values are often members of more complex | ||
17 | // structures (slices, maps, etc.) that are walkable by other interfaces. | ||
18 | type PrimitiveWalker interface { | ||
19 | Primitive(reflect.Value) error | ||
20 | } | ||
21 | |||
22 | // InterfaceWalker implementations are able to handle interface values as they | ||
23 | // are encountered during the walk. | ||
24 | type InterfaceWalker interface { | ||
25 | Interface(reflect.Value) error | ||
26 | } | ||
27 | |||
28 | // MapWalker implementations are able to handle individual elements | ||
29 | // found within a map structure. | ||
30 | type MapWalker interface { | ||
31 | Map(m reflect.Value) error | ||
32 | MapElem(m, k, v reflect.Value) error | ||
33 | } | ||
34 | |||
35 | // SliceWalker implementations are able to handle slice elements found | ||
36 | // within complex structures. | ||
37 | type SliceWalker interface { | ||
38 | Slice(reflect.Value) error | ||
39 | SliceElem(int, reflect.Value) error | ||
40 | } | ||
41 | |||
42 | // StructWalker is an interface that has methods that are called for | ||
43 | // structs when a Walk is done. | ||
44 | type StructWalker interface { | ||
45 | Struct(reflect.Value) error | ||
46 | StructField(reflect.StructField, reflect.Value) error | ||
47 | } | ||
48 | |||
49 | // EnterExitWalker implementations are notified before and after | ||
50 | // they walk deeper into complex structures (into struct fields, | ||
51 | // into slice elements, etc.) | ||
52 | type EnterExitWalker interface { | ||
53 | Enter(Location) error | ||
54 | Exit(Location) error | ||
55 | } | ||
56 | |||
57 | // PointerWalker implementations are notified when the value they're | ||
58 | // walking is a pointer or not. Pointer is called for _every_ value whether | ||
59 | // it is a pointer or not. | ||
60 | type PointerWalker interface { | ||
61 | PointerEnter(bool) error | ||
62 | PointerExit(bool) error | ||
63 | } | ||
64 | |||
65 | // SkipEntry can be returned from walk functions to skip walking | ||
66 | // the value of this field. This is only valid in the following functions: | ||
67 | // | ||
68 | // - StructField: skips walking the struct value | ||
69 | // | ||
70 | var SkipEntry = errors.New("skip this entry") | ||
71 | |||
72 | // Walk takes an arbitrary value and an interface and traverses the | ||
73 | // value, calling callbacks on the interface if they are supported. | ||
74 | // The interface should implement one or more of the walker interfaces | ||
75 | // in this package, such as PrimitiveWalker, StructWalker, etc. | ||
76 | func Walk(data, walker interface{}) (err error) { | ||
77 | v := reflect.ValueOf(data) | ||
78 | ew, ok := walker.(EnterExitWalker) | ||
79 | if ok { | ||
80 | err = ew.Enter(WalkLoc) | ||
81 | } | ||
82 | |||
83 | if err == nil { | ||
84 | err = walk(v, walker) | ||
85 | } | ||
86 | |||
87 | if ok && err == nil { | ||
88 | err = ew.Exit(WalkLoc) | ||
89 | } | ||
90 | |||
91 | return | ||
92 | } | ||
93 | |||
94 | func walk(v reflect.Value, w interface{}) (err error) { | ||
95 | // Determine if we're receiving a pointer and if so notify the walker. | ||
96 | // The logic here is convoluted but very important (tests will fail if | ||
97 | // almost any part is changed). I will try to explain here. | ||
98 | // | ||
99 | // First, we check if the value is an interface, if so, we really need | ||
100 | // to check the interface's VALUE to see whether it is a pointer. | ||
101 | // | ||
102 | // Check whether the value is then a pointer. If so, then set pointer | ||
103 | // to true to notify the user. | ||
104 | // | ||
105 | // If we still have a pointer or an interface after the indirections, then | ||
106 | // we unwrap another level | ||
107 | // | ||
108 | // At this time, we also set "v" to be the dereferenced value. This is | ||
109 | // because once we've unwrapped the pointer we want to use that value. | ||
110 | pointer := false | ||
111 | pointerV := v | ||
112 | |||
113 | for { | ||
114 | if pointerV.Kind() == reflect.Interface { | ||
115 | if iw, ok := w.(InterfaceWalker); ok { | ||
116 | if err = iw.Interface(pointerV); err != nil { | ||
117 | return | ||
118 | } | ||
119 | } | ||
120 | |||
121 | pointerV = pointerV.Elem() | ||
122 | } | ||
123 | |||
124 | if pointerV.Kind() == reflect.Ptr { | ||
125 | pointer = true | ||
126 | v = reflect.Indirect(pointerV) | ||
127 | } | ||
128 | if pw, ok := w.(PointerWalker); ok { | ||
129 | if err = pw.PointerEnter(pointer); err != nil { | ||
130 | return | ||
131 | } | ||
132 | |||
133 | defer func(pointer bool) { | ||
134 | if err != nil { | ||
135 | return | ||
136 | } | ||
137 | |||
138 | err = pw.PointerExit(pointer) | ||
139 | }(pointer) | ||
140 | } | ||
141 | |||
142 | if pointer { | ||
143 | pointerV = v | ||
144 | } | ||
145 | pointer = false | ||
146 | |||
147 | // If we still have a pointer or interface we have to indirect another level. | ||
148 | switch pointerV.Kind() { | ||
149 | case reflect.Ptr, reflect.Interface: | ||
150 | continue | ||
151 | } | ||
152 | break | ||
153 | } | ||
154 | |||
155 | // We preserve the original value here because if it is an interface | ||
156 | // type, we want to pass that directly into the walkPrimitive, so that | ||
157 | // we can set it. | ||
158 | originalV := v | ||
159 | if v.Kind() == reflect.Interface { | ||
160 | v = v.Elem() | ||
161 | } | ||
162 | |||
163 | k := v.Kind() | ||
164 | if k >= reflect.Int && k <= reflect.Complex128 { | ||
165 | k = reflect.Int | ||
166 | } | ||
167 | |||
168 | switch k { | ||
169 | // Primitives | ||
170 | case reflect.Bool, reflect.Chan, reflect.Func, reflect.Int, reflect.String, reflect.Invalid: | ||
171 | err = walkPrimitive(originalV, w) | ||
172 | return | ||
173 | case reflect.Map: | ||
174 | err = walkMap(v, w) | ||
175 | return | ||
176 | case reflect.Slice: | ||
177 | err = walkSlice(v, w) | ||
178 | return | ||
179 | case reflect.Struct: | ||
180 | err = walkStruct(v, w) | ||
181 | return | ||
182 | default: | ||
183 | panic("unsupported type: " + k.String()) | ||
184 | } | ||
185 | } | ||
186 | |||
187 | func walkMap(v reflect.Value, w interface{}) error { | ||
188 | ew, ewok := w.(EnterExitWalker) | ||
189 | if ewok { | ||
190 | ew.Enter(Map) | ||
191 | } | ||
192 | |||
193 | if mw, ok := w.(MapWalker); ok { | ||
194 | if err := mw.Map(v); err != nil { | ||
195 | return err | ||
196 | } | ||
197 | } | ||
198 | |||
199 | for _, k := range v.MapKeys() { | ||
200 | kv := v.MapIndex(k) | ||
201 | |||
202 | if mw, ok := w.(MapWalker); ok { | ||
203 | if err := mw.MapElem(v, k, kv); err != nil { | ||
204 | return err | ||
205 | } | ||
206 | } | ||
207 | |||
208 | ew, ok := w.(EnterExitWalker) | ||
209 | if ok { | ||
210 | ew.Enter(MapKey) | ||
211 | } | ||
212 | |||
213 | if err := walk(k, w); err != nil { | ||
214 | return err | ||
215 | } | ||
216 | |||
217 | if ok { | ||
218 | ew.Exit(MapKey) | ||
219 | ew.Enter(MapValue) | ||
220 | } | ||
221 | |||
222 | if err := walk(kv, w); err != nil { | ||
223 | return err | ||
224 | } | ||
225 | |||
226 | if ok { | ||
227 | ew.Exit(MapValue) | ||
228 | } | ||
229 | } | ||
230 | |||
231 | if ewok { | ||
232 | ew.Exit(Map) | ||
233 | } | ||
234 | |||
235 | return nil | ||
236 | } | ||
237 | |||
238 | func walkPrimitive(v reflect.Value, w interface{}) error { | ||
239 | if pw, ok := w.(PrimitiveWalker); ok { | ||
240 | return pw.Primitive(v) | ||
241 | } | ||
242 | |||
243 | return nil | ||
244 | } | ||
245 | |||
246 | func walkSlice(v reflect.Value, w interface{}) (err error) { | ||
247 | ew, ok := w.(EnterExitWalker) | ||
248 | if ok { | ||
249 | ew.Enter(Slice) | ||
250 | } | ||
251 | |||
252 | if sw, ok := w.(SliceWalker); ok { | ||
253 | if err := sw.Slice(v); err != nil { | ||
254 | return err | ||
255 | } | ||
256 | } | ||
257 | |||
258 | for i := 0; i < v.Len(); i++ { | ||
259 | elem := v.Index(i) | ||
260 | |||
261 | if sw, ok := w.(SliceWalker); ok { | ||
262 | if err := sw.SliceElem(i, elem); err != nil { | ||
263 | return err | ||
264 | } | ||
265 | } | ||
266 | |||
267 | ew, ok := w.(EnterExitWalker) | ||
268 | if ok { | ||
269 | ew.Enter(SliceElem) | ||
270 | } | ||
271 | |||
272 | if err := walk(elem, w); err != nil { | ||
273 | return err | ||
274 | } | ||
275 | |||
276 | if ok { | ||
277 | ew.Exit(SliceElem) | ||
278 | } | ||
279 | } | ||
280 | |||
281 | ew, ok = w.(EnterExitWalker) | ||
282 | if ok { | ||
283 | ew.Exit(Slice) | ||
284 | } | ||
285 | |||
286 | return nil | ||
287 | } | ||
288 | |||
289 | func walkStruct(v reflect.Value, w interface{}) (err error) { | ||
290 | ew, ewok := w.(EnterExitWalker) | ||
291 | if ewok { | ||
292 | ew.Enter(Struct) | ||
293 | } | ||
294 | |||
295 | if sw, ok := w.(StructWalker); ok { | ||
296 | if err = sw.Struct(v); err != nil { | ||
297 | return | ||
298 | } | ||
299 | } | ||
300 | |||
301 | vt := v.Type() | ||
302 | for i := 0; i < vt.NumField(); i++ { | ||
303 | sf := vt.Field(i) | ||
304 | f := v.FieldByIndex([]int{i}) | ||
305 | |||
306 | if sw, ok := w.(StructWalker); ok { | ||
307 | err = sw.StructField(sf, f) | ||
308 | |||
309 | // SkipEntry just pretends this field doesn't even exist | ||
310 | if err == SkipEntry { | ||
311 | continue | ||
312 | } | ||
313 | |||
314 | if err != nil { | ||
315 | return | ||
316 | } | ||
317 | } | ||
318 | |||
319 | ew, ok := w.(EnterExitWalker) | ||
320 | if ok { | ||
321 | ew.Enter(StructField) | ||
322 | } | ||
323 | |||
324 | err = walk(f, w) | ||
325 | if err != nil { | ||
326 | return | ||
327 | } | ||
328 | |||
329 | if ok { | ||
330 | ew.Exit(StructField) | ||
331 | } | ||
332 | } | ||
333 | |||
334 | if ewok { | ||
335 | ew.Exit(Struct) | ||
336 | } | ||
337 | |||
338 | return nil | ||
339 | } | ||