diff options
Diffstat (limited to 'vendor/github.com/mitchellh/copystructure')
-rw-r--r-- | vendor/github.com/mitchellh/copystructure/.travis.yml | 12 | ||||
-rw-r--r-- | vendor/github.com/mitchellh/copystructure/copystructure.go | 87 |
2 files changed, 91 insertions, 8 deletions
diff --git a/vendor/github.com/mitchellh/copystructure/.travis.yml b/vendor/github.com/mitchellh/copystructure/.travis.yml new file mode 100644 index 0000000..d7b9589 --- /dev/null +++ b/vendor/github.com/mitchellh/copystructure/.travis.yml | |||
@@ -0,0 +1,12 @@ | |||
1 | language: go | ||
2 | |||
3 | go: | ||
4 | - 1.7 | ||
5 | - tip | ||
6 | |||
7 | script: | ||
8 | - go test | ||
9 | |||
10 | matrix: | ||
11 | allow_failures: | ||
12 | - go: tip | ||
diff --git a/vendor/github.com/mitchellh/copystructure/copystructure.go b/vendor/github.com/mitchellh/copystructure/copystructure.go index 0e725ea..1404352 100644 --- a/vendor/github.com/mitchellh/copystructure/copystructure.go +++ b/vendor/github.com/mitchellh/copystructure/copystructure.go | |||
@@ -156,9 +156,13 @@ func (w *walker) Exit(l reflectwalk.Location) error { | |||
156 | } | 156 | } |
157 | 157 | ||
158 | switch l { | 158 | switch l { |
159 | case reflectwalk.Array: | ||
160 | fallthrough | ||
159 | case reflectwalk.Map: | 161 | case reflectwalk.Map: |
160 | fallthrough | 162 | fallthrough |
161 | case reflectwalk.Slice: | 163 | case reflectwalk.Slice: |
164 | w.replacePointerMaybe() | ||
165 | |||
162 | // Pop map off our container | 166 | // Pop map off our container |
163 | w.cs = w.cs[:len(w.cs)-1] | 167 | w.cs = w.cs[:len(w.cs)-1] |
164 | case reflectwalk.MapValue: | 168 | case reflectwalk.MapValue: |
@@ -171,16 +175,27 @@ func (w *walker) Exit(l reflectwalk.Location) error { | |||
171 | // or in this case never adds it. We need to create a properly typed | 175 | // or in this case never adds it. We need to create a properly typed |
172 | // zero value so that this key can be set. | 176 | // zero value so that this key can be set. |
173 | if !mv.IsValid() { | 177 | if !mv.IsValid() { |
174 | mv = reflect.Zero(m.Type().Elem()) | 178 | mv = reflect.Zero(m.Elem().Type().Elem()) |
179 | } | ||
180 | m.Elem().SetMapIndex(mk, mv) | ||
181 | case reflectwalk.ArrayElem: | ||
182 | // Pop off the value and the index and set it on the array | ||
183 | v := w.valPop() | ||
184 | i := w.valPop().Interface().(int) | ||
185 | if v.IsValid() { | ||
186 | a := w.cs[len(w.cs)-1] | ||
187 | ae := a.Elem().Index(i) // storing array as pointer on stack - so need Elem() call | ||
188 | if ae.CanSet() { | ||
189 | ae.Set(v) | ||
190 | } | ||
175 | } | 191 | } |
176 | m.SetMapIndex(mk, mv) | ||
177 | case reflectwalk.SliceElem: | 192 | case reflectwalk.SliceElem: |
178 | // Pop off the value and the index and set it on the slice | 193 | // Pop off the value and the index and set it on the slice |
179 | v := w.valPop() | 194 | v := w.valPop() |
180 | i := w.valPop().Interface().(int) | 195 | i := w.valPop().Interface().(int) |
181 | if v.IsValid() { | 196 | if v.IsValid() { |
182 | s := w.cs[len(w.cs)-1] | 197 | s := w.cs[len(w.cs)-1] |
183 | se := s.Index(i) | 198 | se := s.Elem().Index(i) |
184 | if se.CanSet() { | 199 | if se.CanSet() { |
185 | se.Set(v) | 200 | se.Set(v) |
186 | } | 201 | } |
@@ -220,9 +235,9 @@ func (w *walker) Map(m reflect.Value) error { | |||
220 | // Create the map. If the map itself is nil, then just make a nil map | 235 | // Create the map. If the map itself is nil, then just make a nil map |
221 | var newMap reflect.Value | 236 | var newMap reflect.Value |
222 | if m.IsNil() { | 237 | if m.IsNil() { |
223 | newMap = reflect.Indirect(reflect.New(m.Type())) | 238 | newMap = reflect.New(m.Type()) |
224 | } else { | 239 | } else { |
225 | newMap = reflect.MakeMap(m.Type()) | 240 | newMap = wrapPtr(reflect.MakeMap(m.Type())) |
226 | } | 241 | } |
227 | 242 | ||
228 | w.cs = append(w.cs, newMap) | 243 | w.cs = append(w.cs, newMap) |
@@ -287,9 +302,9 @@ func (w *walker) Slice(s reflect.Value) error { | |||
287 | 302 | ||
288 | var newS reflect.Value | 303 | var newS reflect.Value |
289 | if s.IsNil() { | 304 | if s.IsNil() { |
290 | newS = reflect.Indirect(reflect.New(s.Type())) | 305 | newS = reflect.New(s.Type()) |
291 | } else { | 306 | } else { |
292 | newS = reflect.MakeSlice(s.Type(), s.Len(), s.Cap()) | 307 | newS = wrapPtr(reflect.MakeSlice(s.Type(), s.Len(), s.Cap())) |
293 | } | 308 | } |
294 | 309 | ||
295 | w.cs = append(w.cs, newS) | 310 | w.cs = append(w.cs, newS) |
@@ -309,6 +324,31 @@ func (w *walker) SliceElem(i int, elem reflect.Value) error { | |||
309 | return nil | 324 | return nil |
310 | } | 325 | } |
311 | 326 | ||
327 | func (w *walker) Array(a reflect.Value) error { | ||
328 | if w.ignoring() { | ||
329 | return nil | ||
330 | } | ||
331 | w.lock(a) | ||
332 | |||
333 | newA := reflect.New(a.Type()) | ||
334 | |||
335 | w.cs = append(w.cs, newA) | ||
336 | w.valPush(newA) | ||
337 | return nil | ||
338 | } | ||
339 | |||
340 | func (w *walker) ArrayElem(i int, elem reflect.Value) error { | ||
341 | if w.ignoring() { | ||
342 | return nil | ||
343 | } | ||
344 | |||
345 | // We don't write the array here because elem might still be | ||
346 | // arbitrarily complex. Just record the index and continue on. | ||
347 | w.valPush(reflect.ValueOf(i)) | ||
348 | |||
349 | return nil | ||
350 | } | ||
351 | |||
312 | func (w *walker) Struct(s reflect.Value) error { | 352 | func (w *walker) Struct(s reflect.Value) error { |
313 | if w.ignoring() { | 353 | if w.ignoring() { |
314 | return nil | 354 | return nil |
@@ -326,7 +366,10 @@ func (w *walker) Struct(s reflect.Value) error { | |||
326 | return err | 366 | return err |
327 | } | 367 | } |
328 | 368 | ||
329 | v = reflect.ValueOf(dup) | 369 | // We need to put a pointer to the value on the value stack, |
370 | // so allocate a new pointer and set it. | ||
371 | v = reflect.New(s.Type()) | ||
372 | reflect.Indirect(v).Set(reflect.ValueOf(dup)) | ||
330 | } else { | 373 | } else { |
331 | // No copier, we copy ourselves and allow reflectwalk to guide | 374 | // No copier, we copy ourselves and allow reflectwalk to guide |
332 | // us deeper into the structure for copying. | 375 | // us deeper into the structure for copying. |
@@ -405,6 +448,23 @@ func (w *walker) replacePointerMaybe() { | |||
405 | } | 448 | } |
406 | 449 | ||
407 | v := w.valPop() | 450 | v := w.valPop() |
451 | |||
452 | // If the expected type is a pointer to an interface of any depth, | ||
453 | // such as *interface{}, **interface{}, etc., then we need to convert | ||
454 | // the value "v" from *CONCRETE to *interface{} so types match for | ||
455 | // Set. | ||
456 | // | ||
457 | // Example if v is type *Foo where Foo is a struct, v would become | ||
458 | // *interface{} instead. This only happens if we have an interface expectation | ||
459 | // at this depth. | ||
460 | // | ||
461 | // For more info, see GH-16 | ||
462 | if iType, ok := w.ifaceTypes[ifaceKey(w.ps[w.depth], w.depth)]; ok && iType.Kind() == reflect.Interface { | ||
463 | y := reflect.New(iType) // Create *interface{} | ||
464 | y.Elem().Set(reflect.Indirect(v)) // Assign "Foo" to interface{} (dereferenced) | ||
465 | v = y // v is now typed *interface{} (where *v = Foo) | ||
466 | } | ||
467 | |||
408 | for i := 1; i < w.ps[w.depth]; i++ { | 468 | for i := 1; i < w.ps[w.depth]; i++ { |
409 | if iType, ok := w.ifaceTypes[ifaceKey(w.ps[w.depth]-i, w.depth)]; ok { | 469 | if iType, ok := w.ifaceTypes[ifaceKey(w.ps[w.depth]-i, w.depth)]; ok { |
410 | iface := reflect.New(iType).Elem() | 470 | iface := reflect.New(iType).Elem() |
@@ -475,3 +535,14 @@ func (w *walker) lock(v reflect.Value) { | |||
475 | locker.Lock() | 535 | locker.Lock() |
476 | w.locks[w.depth] = locker | 536 | w.locks[w.depth] = locker |
477 | } | 537 | } |
538 | |||
539 | // wrapPtr is a helper that takes v and always make it *v. copystructure | ||
540 | // stores things internally as pointers until the last moment before unwrapping | ||
541 | func wrapPtr(v reflect.Value) reflect.Value { | ||
542 | if !v.IsValid() { | ||
543 | return v | ||
544 | } | ||
545 | vPtr := reflect.New(v.Type()) | ||
546 | vPtr.Elem().Set(v) | ||
547 | return vPtr | ||
548 | } | ||