aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/mitchellh/mapstructure/mapstructure.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/mitchellh/mapstructure/mapstructure.go')
-rw-r--r--vendor/github.com/mitchellh/mapstructure/mapstructure.go520
1 files changed, 423 insertions, 97 deletions
diff --git a/vendor/github.com/mitchellh/mapstructure/mapstructure.go b/vendor/github.com/mitchellh/mapstructure/mapstructure.go
index 6dee0ef..256ee63 100644
--- a/vendor/github.com/mitchellh/mapstructure/mapstructure.go
+++ b/vendor/github.com/mitchellh/mapstructure/mapstructure.go
@@ -1,5 +1,5 @@
1// The mapstructure package exposes functionality to convert an 1// Package mapstructure exposes functionality to convert an arbitrary
2// arbitrary map[string]interface{} into a native Go structure. 2// map[string]interface{} into a native Go structure.
3// 3//
4// The Go structure can be arbitrarily complex, containing slices, 4// The Go structure can be arbitrarily complex, containing slices,
5// other structs, etc. and the decoder will properly decode nested 5// other structs, etc. and the decoder will properly decode nested
@@ -32,7 +32,12 @@ import (
32// both. 32// both.
33type DecodeHookFunc interface{} 33type DecodeHookFunc interface{}
34 34
35// DecodeHookFuncType is a DecodeHookFunc which has complete information about
36// the source and target types.
35type DecodeHookFuncType func(reflect.Type, reflect.Type, interface{}) (interface{}, error) 37type DecodeHookFuncType func(reflect.Type, reflect.Type, interface{}) (interface{}, error)
38
39// DecodeHookFuncKind is a DecodeHookFunc which knows only the Kinds of the
40// source and target types.
36type DecodeHookFuncKind func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error) 41type DecodeHookFuncKind func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error)
37 42
38// DecoderConfig is the configuration that is used to create a new decoder 43// DecoderConfig is the configuration that is used to create a new decoder
@@ -109,12 +114,12 @@ type Metadata struct {
109 Unused []string 114 Unused []string
110} 115}
111 116
112// Decode takes a map and uses reflection to convert it into the 117// Decode takes an input structure and uses reflection to translate it to
113// given Go native structure. val must be a pointer to a struct. 118// the output structure. output must be a pointer to a map or struct.
114func Decode(m interface{}, rawVal interface{}) error { 119func Decode(input interface{}, output interface{}) error {
115 config := &DecoderConfig{ 120 config := &DecoderConfig{
116 Metadata: nil, 121 Metadata: nil,
117 Result: rawVal, 122 Result: output,
118 } 123 }
119 124
120 decoder, err := NewDecoder(config) 125 decoder, err := NewDecoder(config)
@@ -122,7 +127,7 @@ func Decode(m interface{}, rawVal interface{}) error {
122 return err 127 return err
123 } 128 }
124 129
125 return decoder.Decode(m) 130 return decoder.Decode(input)
126} 131}
127 132
128// WeakDecode is the same as Decode but is shorthand to enable 133// WeakDecode is the same as Decode but is shorthand to enable
@@ -142,6 +147,40 @@ func WeakDecode(input, output interface{}) error {
142 return decoder.Decode(input) 147 return decoder.Decode(input)
143} 148}
144 149
150// DecodeMetadata is the same as Decode, but is shorthand to
151// enable metadata collection. See DecoderConfig for more info.
152func DecodeMetadata(input interface{}, output interface{}, metadata *Metadata) error {
153 config := &DecoderConfig{
154 Metadata: metadata,
155 Result: output,
156 }
157
158 decoder, err := NewDecoder(config)
159 if err != nil {
160 return err
161 }
162
163 return decoder.Decode(input)
164}
165
166// WeakDecodeMetadata is the same as Decode, but is shorthand to
167// enable both WeaklyTypedInput and metadata collection. See
168// DecoderConfig for more info.
169func WeakDecodeMetadata(input interface{}, output interface{}, metadata *Metadata) error {
170 config := &DecoderConfig{
171 Metadata: metadata,
172 Result: output,
173 WeaklyTypedInput: true,
174 }
175
176 decoder, err := NewDecoder(config)
177 if err != nil {
178 return err
179 }
180
181 return decoder.Decode(input)
182}
183
145// NewDecoder returns a new decoder for the given configuration. Once 184// NewDecoder returns a new decoder for the given configuration. Once
146// a decoder has been returned, the same configuration must not be used 185// a decoder has been returned, the same configuration must not be used
147// again. 186// again.
@@ -179,68 +218,91 @@ func NewDecoder(config *DecoderConfig) (*Decoder, error) {
179 218
180// Decode decodes the given raw interface to the target pointer specified 219// Decode decodes the given raw interface to the target pointer specified
181// by the configuration. 220// by the configuration.
182func (d *Decoder) Decode(raw interface{}) error { 221func (d *Decoder) Decode(input interface{}) error {
183 return d.decode("", raw, reflect.ValueOf(d.config.Result).Elem()) 222 return d.decode("", input, reflect.ValueOf(d.config.Result).Elem())
184} 223}
185 224
186// Decodes an unknown data type into a specific reflection value. 225// Decodes an unknown data type into a specific reflection value.
187func (d *Decoder) decode(name string, data interface{}, val reflect.Value) error { 226func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) error {
188 if data == nil { 227 var inputVal reflect.Value
189 // If the data is nil, then we don't set anything. 228 if input != nil {
229 inputVal = reflect.ValueOf(input)
230
231 // We need to check here if input is a typed nil. Typed nils won't
232 // match the "input == nil" below so we check that here.
233 if inputVal.Kind() == reflect.Ptr && inputVal.IsNil() {
234 input = nil
235 }
236 }
237
238 if input == nil {
239 // If the data is nil, then we don't set anything, unless ZeroFields is set
240 // to true.
241 if d.config.ZeroFields {
242 outVal.Set(reflect.Zero(outVal.Type()))
243
244 if d.config.Metadata != nil && name != "" {
245 d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
246 }
247 }
190 return nil 248 return nil
191 } 249 }
192 250
193 dataVal := reflect.ValueOf(data) 251 if !inputVal.IsValid() {
194 if !dataVal.IsValid() { 252 // If the input value is invalid, then we just set the value
195 // If the data value is invalid, then we just set the value
196 // to be the zero value. 253 // to be the zero value.
197 val.Set(reflect.Zero(val.Type())) 254 outVal.Set(reflect.Zero(outVal.Type()))
255 if d.config.Metadata != nil && name != "" {
256 d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
257 }
198 return nil 258 return nil
199 } 259 }
200 260
201 if d.config.DecodeHook != nil { 261 if d.config.DecodeHook != nil {
202 // We have a DecodeHook, so let's pre-process the data. 262 // We have a DecodeHook, so let's pre-process the input.
203 var err error 263 var err error
204 data, err = DecodeHookExec( 264 input, err = DecodeHookExec(
205 d.config.DecodeHook, 265 d.config.DecodeHook,
206 dataVal.Type(), val.Type(), data) 266 inputVal.Type(), outVal.Type(), input)
207 if err != nil { 267 if err != nil {
208 return fmt.Errorf("error decoding '%s': %s", name, err) 268 return fmt.Errorf("error decoding '%s': %s", name, err)
209 } 269 }
210 } 270 }
211 271
212 var err error 272 var err error
213 dataKind := getKind(val) 273 outputKind := getKind(outVal)
214 switch dataKind { 274 switch outputKind {
215 case reflect.Bool: 275 case reflect.Bool:
216 err = d.decodeBool(name, data, val) 276 err = d.decodeBool(name, input, outVal)
217 case reflect.Interface: 277 case reflect.Interface:
218 err = d.decodeBasic(name, data, val) 278 err = d.decodeBasic(name, input, outVal)
219 case reflect.String: 279 case reflect.String:
220 err = d.decodeString(name, data, val) 280 err = d.decodeString(name, input, outVal)
221 case reflect.Int: 281 case reflect.Int:
222 err = d.decodeInt(name, data, val) 282 err = d.decodeInt(name, input, outVal)
223 case reflect.Uint: 283 case reflect.Uint:
224 err = d.decodeUint(name, data, val) 284 err = d.decodeUint(name, input, outVal)
225 case reflect.Float32: 285 case reflect.Float32:
226 err = d.decodeFloat(name, data, val) 286 err = d.decodeFloat(name, input, outVal)
227 case reflect.Struct: 287 case reflect.Struct:
228 err = d.decodeStruct(name, data, val) 288 err = d.decodeStruct(name, input, outVal)
229 case reflect.Map: 289 case reflect.Map:
230 err = d.decodeMap(name, data, val) 290 err = d.decodeMap(name, input, outVal)
231 case reflect.Ptr: 291 case reflect.Ptr:
232 err = d.decodePtr(name, data, val) 292 err = d.decodePtr(name, input, outVal)
233 case reflect.Slice: 293 case reflect.Slice:
234 err = d.decodeSlice(name, data, val) 294 err = d.decodeSlice(name, input, outVal)
295 case reflect.Array:
296 err = d.decodeArray(name, input, outVal)
235 case reflect.Func: 297 case reflect.Func:
236 err = d.decodeFunc(name, data, val) 298 err = d.decodeFunc(name, input, outVal)
237 default: 299 default:
238 // If we reached this point then we weren't able to decode it 300 // If we reached this point then we weren't able to decode it
239 return fmt.Errorf("%s: unsupported type: %s", name, dataKind) 301 return fmt.Errorf("%s: unsupported type: %s", name, outputKind)
240 } 302 }
241 303
242 // If we reached here, then we successfully decoded SOMETHING, so 304 // If we reached here, then we successfully decoded SOMETHING, so
243 // mark the key as used if we're tracking metadata. 305 // mark the key as used if we're tracking metainput.
244 if d.config.Metadata != nil && name != "" { 306 if d.config.Metadata != nil && name != "" {
245 d.config.Metadata.Keys = append(d.config.Metadata.Keys, name) 307 d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
246 } 308 }
@@ -251,7 +313,19 @@ func (d *Decoder) decode(name string, data interface{}, val reflect.Value) error
251// This decodes a basic type (bool, int, string, etc.) and sets the 313// This decodes a basic type (bool, int, string, etc.) and sets the
252// value to "data" of that type. 314// value to "data" of that type.
253func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error { 315func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error {
316 if val.IsValid() && val.Elem().IsValid() {
317 return d.decode(name, data, val.Elem())
318 }
319
254 dataVal := reflect.ValueOf(data) 320 dataVal := reflect.ValueOf(data)
321
322 // If the input data is a pointer, and the assigned type is the dereference
323 // of that exact pointer, then indirect it so that we can assign it.
324 // Example: *string to string
325 if dataVal.Kind() == reflect.Ptr && dataVal.Type().Elem() == val.Type() {
326 dataVal = reflect.Indirect(dataVal)
327 }
328
255 if !dataVal.IsValid() { 329 if !dataVal.IsValid() {
256 dataVal = reflect.Zero(val.Type()) 330 dataVal = reflect.Zero(val.Type())
257 } 331 }
@@ -268,7 +342,7 @@ func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value)
268} 342}
269 343
270func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) error { 344func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) error {
271 dataVal := reflect.ValueOf(data) 345 dataVal := reflect.Indirect(reflect.ValueOf(data))
272 dataKind := getKind(dataVal) 346 dataKind := getKind(dataVal)
273 347
274 converted := true 348 converted := true
@@ -287,12 +361,22 @@ func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value)
287 val.SetString(strconv.FormatUint(dataVal.Uint(), 10)) 361 val.SetString(strconv.FormatUint(dataVal.Uint(), 10))
288 case dataKind == reflect.Float32 && d.config.WeaklyTypedInput: 362 case dataKind == reflect.Float32 && d.config.WeaklyTypedInput:
289 val.SetString(strconv.FormatFloat(dataVal.Float(), 'f', -1, 64)) 363 val.SetString(strconv.FormatFloat(dataVal.Float(), 'f', -1, 64))
290 case dataKind == reflect.Slice && d.config.WeaklyTypedInput: 364 case dataKind == reflect.Slice && d.config.WeaklyTypedInput,
365 dataKind == reflect.Array && d.config.WeaklyTypedInput:
291 dataType := dataVal.Type() 366 dataType := dataVal.Type()
292 elemKind := dataType.Elem().Kind() 367 elemKind := dataType.Elem().Kind()
293 switch { 368 switch elemKind {
294 case elemKind == reflect.Uint8: 369 case reflect.Uint8:
295 val.SetString(string(dataVal.Interface().([]uint8))) 370 var uints []uint8
371 if dataKind == reflect.Array {
372 uints = make([]uint8, dataVal.Len(), dataVal.Len())
373 for i := range uints {
374 uints[i] = dataVal.Index(i).Interface().(uint8)
375 }
376 } else {
377 uints = dataVal.Interface().([]uint8)
378 }
379 val.SetString(string(uints))
296 default: 380 default:
297 converted = false 381 converted = false
298 } 382 }
@@ -310,7 +394,7 @@ func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value)
310} 394}
311 395
312func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) error { 396func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) error {
313 dataVal := reflect.ValueOf(data) 397 dataVal := reflect.Indirect(reflect.ValueOf(data))
314 dataKind := getKind(dataVal) 398 dataKind := getKind(dataVal)
315 dataType := dataVal.Type() 399 dataType := dataVal.Type()
316 400
@@ -352,7 +436,7 @@ func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) er
352} 436}
353 437
354func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) error { 438func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) error {
355 dataVal := reflect.ValueOf(data) 439 dataVal := reflect.Indirect(reflect.ValueOf(data))
356 dataKind := getKind(dataVal) 440 dataKind := getKind(dataVal)
357 441
358 switch { 442 switch {
@@ -395,7 +479,7 @@ func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) e
395} 479}
396 480
397func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) error { 481func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) error {
398 dataVal := reflect.ValueOf(data) 482 dataVal := reflect.Indirect(reflect.ValueOf(data))
399 dataKind := getKind(dataVal) 483 dataKind := getKind(dataVal)
400 484
401 switch { 485 switch {
@@ -426,7 +510,7 @@ func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) e
426} 510}
427 511
428func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) error { 512func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) error {
429 dataVal := reflect.ValueOf(data) 513 dataVal := reflect.Indirect(reflect.ValueOf(data))
430 dataKind := getKind(dataVal) 514 dataKind := getKind(dataVal)
431 dataType := dataVal.Type() 515 dataType := dataVal.Type()
432 516
@@ -436,7 +520,7 @@ func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value)
436 case dataKind == reflect.Uint: 520 case dataKind == reflect.Uint:
437 val.SetFloat(float64(dataVal.Uint())) 521 val.SetFloat(float64(dataVal.Uint()))
438 case dataKind == reflect.Float32: 522 case dataKind == reflect.Float32:
439 val.SetFloat(float64(dataVal.Float())) 523 val.SetFloat(dataVal.Float())
440 case dataKind == reflect.Bool && d.config.WeaklyTypedInput: 524 case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
441 if dataVal.Bool() { 525 if dataVal.Bool() {
442 val.SetFloat(1) 526 val.SetFloat(1)
@@ -482,38 +566,68 @@ func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) er
482 valMap = reflect.MakeMap(mapType) 566 valMap = reflect.MakeMap(mapType)
483 } 567 }
484 568
485 // Check input type 569 // Check input type and based on the input type jump to the proper func
486 dataVal := reflect.Indirect(reflect.ValueOf(data)) 570 dataVal := reflect.Indirect(reflect.ValueOf(data))
487 if dataVal.Kind() != reflect.Map { 571 switch dataVal.Kind() {
488 // In weak mode, we accept a slice of maps as an input... 572 case reflect.Map:
489 if d.config.WeaklyTypedInput { 573 return d.decodeMapFromMap(name, dataVal, val, valMap)
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 574
498 for i := 0; i < dataVal.Len(); i++ { 575 case reflect.Struct:
499 err := d.decode( 576 return d.decodeMapFromStruct(name, dataVal, val, valMap)
500 fmt.Sprintf("%s[%d]", name, i),
501 dataVal.Index(i).Interface(), val)
502 if err != nil {
503 return err
504 }
505 }
506 577
507 return nil 578 case reflect.Array, reflect.Slice:
508 } 579 if d.config.WeaklyTypedInput {
580 return d.decodeMapFromSlice(name, dataVal, val, valMap)
509 } 581 }
510 582
583 fallthrough
584
585 default:
511 return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind()) 586 return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind())
512 } 587 }
588}
589
590func (d *Decoder) decodeMapFromSlice(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {
591 // Special case for BC reasons (covered by tests)
592 if dataVal.Len() == 0 {
593 val.Set(valMap)
594 return nil
595 }
596
597 for i := 0; i < dataVal.Len(); i++ {
598 err := d.decode(
599 fmt.Sprintf("%s[%d]", name, i),
600 dataVal.Index(i).Interface(), val)
601 if err != nil {
602 return err
603 }
604 }
605
606 return nil
607}
608
609func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {
610 valType := val.Type()
611 valKeyType := valType.Key()
612 valElemType := valType.Elem()
513 613
514 // Accumulate errors 614 // Accumulate errors
515 errors := make([]string, 0) 615 errors := make([]string, 0)
516 616
617 // If the input data is empty, then we just match what the input data is.
618 if dataVal.Len() == 0 {
619 if dataVal.IsNil() {
620 if !val.IsNil() {
621 val.Set(dataVal)
622 }
623 } else {
624 // Set to empty allocated value
625 val.Set(valMap)
626 }
627
628 return nil
629 }
630
517 for _, k := range dataVal.MapKeys() { 631 for _, k := range dataVal.MapKeys() {
518 fieldName := fmt.Sprintf("%s[%s]", name, k) 632 fieldName := fmt.Sprintf("%s[%s]", name, k)
519 633
@@ -546,22 +660,128 @@ func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) er
546 return nil 660 return nil
547} 661}
548 662
663func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {
664 typ := dataVal.Type()
665 for i := 0; i < typ.NumField(); i++ {
666 // Get the StructField first since this is a cheap operation. If the
667 // field is unexported, then ignore it.
668 f := typ.Field(i)
669 if f.PkgPath != "" {
670 continue
671 }
672
673 // Next get the actual value of this field and verify it is assignable
674 // to the map value.
675 v := dataVal.Field(i)
676 if !v.Type().AssignableTo(valMap.Type().Elem()) {
677 return fmt.Errorf("cannot assign type '%s' to map value field of type '%s'", v.Type(), valMap.Type().Elem())
678 }
679
680 tagValue := f.Tag.Get(d.config.TagName)
681 tagParts := strings.Split(tagValue, ",")
682
683 // Determine the name of the key in the map
684 keyName := f.Name
685 if tagParts[0] != "" {
686 if tagParts[0] == "-" {
687 continue
688 }
689 keyName = tagParts[0]
690 }
691
692 // If "squash" is specified in the tag, we squash the field down.
693 squash := false
694 for _, tag := range tagParts[1:] {
695 if tag == "squash" {
696 squash = true
697 break
698 }
699 }
700 if squash && v.Kind() != reflect.Struct {
701 return fmt.Errorf("cannot squash non-struct type '%s'", v.Type())
702 }
703
704 switch v.Kind() {
705 // this is an embedded struct, so handle it differently
706 case reflect.Struct:
707 x := reflect.New(v.Type())
708 x.Elem().Set(v)
709
710 vType := valMap.Type()
711 vKeyType := vType.Key()
712 vElemType := vType.Elem()
713 mType := reflect.MapOf(vKeyType, vElemType)
714 vMap := reflect.MakeMap(mType)
715
716 err := d.decode(keyName, x.Interface(), vMap)
717 if err != nil {
718 return err
719 }
720
721 if squash {
722 for _, k := range vMap.MapKeys() {
723 valMap.SetMapIndex(k, vMap.MapIndex(k))
724 }
725 } else {
726 valMap.SetMapIndex(reflect.ValueOf(keyName), vMap)
727 }
728
729 default:
730 valMap.SetMapIndex(reflect.ValueOf(keyName), v)
731 }
732 }
733
734 if val.CanAddr() {
735 val.Set(valMap)
736 }
737
738 return nil
739}
740
549func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) error { 741func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) error {
742 // If the input data is nil, then we want to just set the output
743 // pointer to be nil as well.
744 isNil := data == nil
745 if !isNil {
746 switch v := reflect.Indirect(reflect.ValueOf(data)); v.Kind() {
747 case reflect.Chan,
748 reflect.Func,
749 reflect.Interface,
750 reflect.Map,
751 reflect.Ptr,
752 reflect.Slice:
753 isNil = v.IsNil()
754 }
755 }
756 if isNil {
757 if !val.IsNil() && val.CanSet() {
758 nilValue := reflect.New(val.Type()).Elem()
759 val.Set(nilValue)
760 }
761
762 return nil
763 }
764
550 // Create an element of the concrete (non pointer) type and decode 765 // Create an element of the concrete (non pointer) type and decode
551 // into that. Then set the value of the pointer to this type. 766 // into that. Then set the value of the pointer to this type.
552 valType := val.Type() 767 valType := val.Type()
553 valElemType := valType.Elem() 768 valElemType := valType.Elem()
769 if val.CanSet() {
770 realVal := val
771 if realVal.IsNil() || d.config.ZeroFields {
772 realVal = reflect.New(valElemType)
773 }
554 774
555 realVal := val 775 if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil {
556 if realVal.IsNil() || d.config.ZeroFields { 776 return err
557 realVal = reflect.New(valElemType) 777 }
558 }
559 778
560 if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil { 779 val.Set(realVal)
561 return err 780 } else {
781 if err := d.decode(name, data, reflect.Indirect(val)); err != nil {
782 return err
783 }
562 } 784 }
563
564 val.Set(realVal)
565 return nil 785 return nil
566} 786}
567 787
@@ -587,22 +807,101 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
587 807
588 valSlice := val 808 valSlice := val
589 if valSlice.IsNil() || d.config.ZeroFields { 809 if valSlice.IsNil() || d.config.ZeroFields {
810 if d.config.WeaklyTypedInput {
811 switch {
812 // Slice and array we use the normal logic
813 case dataValKind == reflect.Slice, dataValKind == reflect.Array:
814 break
815
816 // Empty maps turn into empty slices
817 case dataValKind == reflect.Map:
818 if dataVal.Len() == 0 {
819 val.Set(reflect.MakeSlice(sliceType, 0, 0))
820 return nil
821 }
822 // Create slice of maps of other sizes
823 return d.decodeSlice(name, []interface{}{data}, val)
824
825 case dataValKind == reflect.String && valElemType.Kind() == reflect.Uint8:
826 return d.decodeSlice(name, []byte(dataVal.String()), val)
827
828 // All other types we try to convert to the slice type
829 // and "lift" it into it. i.e. a string becomes a string slice.
830 default:
831 // Just re-try this function with data as a slice.
832 return d.decodeSlice(name, []interface{}{data}, val)
833 }
834 }
835
836 // Check input type
837 if dataValKind != reflect.Array && dataValKind != reflect.Slice {
838 return fmt.Errorf(
839 "'%s': source data must be an array or slice, got %s", name, dataValKind)
840
841 }
842
843 // If the input value is empty, then don't allocate since non-nil != nil
844 if dataVal.Len() == 0 {
845 return nil
846 }
847
848 // Make a new slice to hold our result, same size as the original data.
849 valSlice = reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len())
850 }
851
852 // Accumulate any errors
853 errors := make([]string, 0)
854
855 for i := 0; i < dataVal.Len(); i++ {
856 currentData := dataVal.Index(i).Interface()
857 for valSlice.Len() <= i {
858 valSlice = reflect.Append(valSlice, reflect.Zero(valElemType))
859 }
860 currentField := valSlice.Index(i)
861
862 fieldName := fmt.Sprintf("%s[%d]", name, i)
863 if err := d.decode(fieldName, currentData, currentField); err != nil {
864 errors = appendErrors(errors, err)
865 }
866 }
867
868 // Finally, set the value to the slice we built up
869 val.Set(valSlice)
870
871 // If there were errors, we return those
872 if len(errors) > 0 {
873 return &Error{errors}
874 }
875
876 return nil
877}
878
879func (d *Decoder) decodeArray(name string, data interface{}, val reflect.Value) error {
880 dataVal := reflect.Indirect(reflect.ValueOf(data))
881 dataValKind := dataVal.Kind()
882 valType := val.Type()
883 valElemType := valType.Elem()
884 arrayType := reflect.ArrayOf(valType.Len(), valElemType)
885
886 valArray := val
887
888 if valArray.Interface() == reflect.Zero(valArray.Type()).Interface() || d.config.ZeroFields {
590 // Check input type 889 // Check input type
591 if dataValKind != reflect.Array && dataValKind != reflect.Slice { 890 if dataValKind != reflect.Array && dataValKind != reflect.Slice {
592 if d.config.WeaklyTypedInput { 891 if d.config.WeaklyTypedInput {
593 switch { 892 switch {
594 // Empty maps turn into empty slices 893 // Empty maps turn into empty arrays
595 case dataValKind == reflect.Map: 894 case dataValKind == reflect.Map:
596 if dataVal.Len() == 0 { 895 if dataVal.Len() == 0 {
597 val.Set(reflect.MakeSlice(sliceType, 0, 0)) 896 val.Set(reflect.Zero(arrayType))
598 return nil 897 return nil
599 } 898 }
600 899
601 // All other types we try to convert to the slice type 900 // All other types we try to convert to the array type
602 // and "lift" it into it. i.e. a string becomes a string slice. 901 // and "lift" it into it. i.e. a string becomes a string array.
603 default: 902 default:
604 // Just re-try this function with data as a slice. 903 // Just re-try this function with data as a slice.
605 return d.decodeSlice(name, []interface{}{data}, val) 904 return d.decodeArray(name, []interface{}{data}, val)
606 } 905 }
607 } 906 }
608 907
@@ -610,9 +909,14 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
610 "'%s': source data must be an array or slice, got %s", name, dataValKind) 909 "'%s': source data must be an array or slice, got %s", name, dataValKind)
611 910
612 } 911 }
912 if dataVal.Len() > arrayType.Len() {
913 return fmt.Errorf(
914 "'%s': expected source data to have length less or equal to %d, got %d", name, arrayType.Len(), dataVal.Len())
613 915
614 // Make a new slice to hold our result, same size as the original data. 916 }
615 valSlice = reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len()) 917
918 // Make a new array to hold our result, same size as the original data.
919 valArray = reflect.New(arrayType).Elem()
616 } 920 }
617 921
618 // Accumulate any errors 922 // Accumulate any errors
@@ -620,10 +924,7 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
620 924
621 for i := 0; i < dataVal.Len(); i++ { 925 for i := 0; i < dataVal.Len(); i++ {
622 currentData := dataVal.Index(i).Interface() 926 currentData := dataVal.Index(i).Interface()
623 for valSlice.Len() <= i { 927 currentField := valArray.Index(i)
624 valSlice = reflect.Append(valSlice, reflect.Zero(valElemType))
625 }
626 currentField := valSlice.Index(i)
627 928
628 fieldName := fmt.Sprintf("%s[%d]", name, i) 929 fieldName := fmt.Sprintf("%s[%d]", name, i)
629 if err := d.decode(fieldName, currentData, currentField); err != nil { 930 if err := d.decode(fieldName, currentData, currentField); err != nil {
@@ -631,8 +932,8 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
631 } 932 }
632 } 933 }
633 934
634 // Finally, set the value to the slice we built up 935 // Finally, set the value to the array we built up
635 val.Set(valSlice) 936 val.Set(valArray)
636 937
637 // If there were errors, we return those 938 // If there were errors, we return those
638 if len(errors) > 0 { 939 if len(errors) > 0 {
@@ -653,10 +954,29 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value)
653 } 954 }
654 955
655 dataValKind := dataVal.Kind() 956 dataValKind := dataVal.Kind()
656 if dataValKind != reflect.Map { 957 switch dataValKind {
657 return fmt.Errorf("'%s' expected a map, got '%s'", name, dataValKind) 958 case reflect.Map:
959 return d.decodeStructFromMap(name, dataVal, val)
960
961 case reflect.Struct:
962 // Not the most efficient way to do this but we can optimize later if
963 // we want to. To convert from struct to struct we go to map first
964 // as an intermediary.
965 m := make(map[string]interface{})
966 mval := reflect.Indirect(reflect.ValueOf(&m))
967 if err := d.decodeMapFromStruct(name, dataVal, mval, mval); err != nil {
968 return err
969 }
970
971 result := d.decodeStructFromMap(name, mval, val)
972 return result
973
974 default:
975 return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind())
658 } 976 }
977}
659 978
979func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) error {
660 dataValType := dataVal.Type() 980 dataValType := dataVal.Type()
661 if kind := dataValType.Key().Kind(); kind != reflect.String && kind != reflect.Interface { 981 if kind := dataValType.Key().Kind(); kind != reflect.String && kind != reflect.Interface {
662 return fmt.Errorf( 982 return fmt.Errorf(
@@ -681,7 +1001,11 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value)
681 1001
682 // Compile the list of all the fields that we're going to be decoding 1002 // Compile the list of all the fields that we're going to be decoding
683 // from all the structs. 1003 // from all the structs.
684 fields := make(map[*reflect.StructField]reflect.Value) 1004 type field struct {
1005 field reflect.StructField
1006 val reflect.Value
1007 }
1008 fields := []field{}
685 for len(structs) > 0 { 1009 for len(structs) > 0 {
686 structVal := structs[0] 1010 structVal := structs[0]
687 structs = structs[1:] 1011 structs = structs[1:]
@@ -707,20 +1031,22 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value)
707 errors = appendErrors(errors, 1031 errors = appendErrors(errors,
708 fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldKind)) 1032 fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldKind))
709 } else { 1033 } else {
710 structs = append(structs, val.FieldByName(fieldType.Name)) 1034 structs = append(structs, structVal.FieldByName(fieldType.Name))
711 } 1035 }
712 continue 1036 continue
713 } 1037 }
714 1038
715 // Normal struct field, store it away 1039 // Normal struct field, store it away
716 fields[&fieldType] = structVal.Field(i) 1040 fields = append(fields, field{fieldType, structVal.Field(i)})
717 } 1041 }
718 } 1042 }
719 1043
720 for fieldType, field := range fields { 1044 // for fieldType, field := range fields {
721 fieldName := fieldType.Name 1045 for _, f := range fields {
1046 field, fieldValue := f.field, f.val
1047 fieldName := field.Name
722 1048
723 tagValue := fieldType.Tag.Get(d.config.TagName) 1049 tagValue := field.Tag.Get(d.config.TagName)
724 tagValue = strings.SplitN(tagValue, ",", 2)[0] 1050 tagValue = strings.SplitN(tagValue, ",", 2)[0]
725 if tagValue != "" { 1051 if tagValue != "" {
726 fieldName = tagValue 1052 fieldName = tagValue
@@ -755,14 +1081,14 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value)
755 // Delete the key we're using from the unused map so we stop tracking 1081 // Delete the key we're using from the unused map so we stop tracking
756 delete(dataValKeysUnused, rawMapKey.Interface()) 1082 delete(dataValKeysUnused, rawMapKey.Interface())
757 1083
758 if !field.IsValid() { 1084 if !fieldValue.IsValid() {
759 // This should never happen 1085 // This should never happen
760 panic("field is not valid") 1086 panic("field is not valid")
761 } 1087 }
762 1088
763 // If we can't set the field, then it is unexported or something, 1089 // If we can't set the field, then it is unexported or something,
764 // and we just continue onwards. 1090 // and we just continue onwards.
765 if !field.CanSet() { 1091 if !fieldValue.CanSet() {
766 continue 1092 continue
767 } 1093 }
768 1094
@@ -772,7 +1098,7 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value)
772 fieldName = fmt.Sprintf("%s.%s", name, fieldName) 1098 fieldName = fmt.Sprintf("%s.%s", name, fieldName)
773 } 1099 }
774 1100
775 if err := d.decode(fieldName, rawMapVal.Interface(), field); err != nil { 1101 if err := d.decode(fieldName, rawMapVal.Interface(), fieldValue); err != nil {
776 errors = appendErrors(errors, err) 1102 errors = appendErrors(errors, err)
777 } 1103 }
778 } 1104 }