1// Package mapstructure exposes functionality to convert an arbitrary
2// 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.
8package mapstructure
9
10import (
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.
33type DecodeHookFunc interface{}
34
35// DecodeHookFuncType is a DecodeHookFunc which has complete information about
36// the source and target types.
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.
41type DecodeHookFuncKind func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error)
42
43// DecoderConfig is the configuration that is used to create a new decoder
44// and allows customization of various aspects of decoding.
45type DecoderConfig struct {
46 // DecodeHook, if set, will be called before any decoding and any
47 // type conversion (if WeaklyTypedInput is on). This lets you modify
48 // the values before they're set down onto the resulting struct.
49 //
50 // If an error is returned, the entire decode will fail with that
51 // error.
52 DecodeHook DecodeHookFunc
53
54 // If ErrorUnused is true, then it is an error for there to exist
55 // keys in the original map that were unused in the decoding process
56 // (extra keys).
57 ErrorUnused bool
58
59 // ZeroFields, if set to true, will zero fields before writing them.
60 // For example, a map will be emptied before decoded values are put in
61 // it. If this is false, a map will be merged.
62 ZeroFields bool
63
64 // If WeaklyTypedInput is true, the decoder will make the following
65 // "weak" conversions:
66 //
67 // - bools to string (true = "1", false = "0")
68 // - numbers to string (base 10)
69 // - bools to int/uint (true = 1, false = 0)
70 // - strings to int/uint (base implied by prefix)
71 // - int to bool (true if value != 0)
72 // - string to bool (accepts: 1, t, T, TRUE, true, True, 0, f, F,
73 // FALSE, false, False. Anything else is an error)
74 // - empty array = empty map and vice versa
75 // - negative numbers to overflowed uint values (base 10)
76 // - slice of maps to a merged map
77 // - single values are converted to slices if required. Each
78 // element is weakly decoded. For example: "4" can become []int{4}
79 // if the target type is an int slice.
80 //
81 WeaklyTypedInput bool
82
83 // Metadata is the struct that will contain extra metadata about
84 // the decoding. If this is nil, then no metadata will be tracked.
85 Metadata *Metadata
86
87 // Result is a pointer to the struct that will contain the decoded
88 // value.
89 Result interface{}
90
91 // The tag name that mapstructure reads for field names. This
92 // defaults to "mapstructure"
93 TagName string
94}
95
96// A Decoder takes a raw interface value and turns it into structured
97// data, keeping track of rich error information along the way in case
98// anything goes wrong. Unlike the basic top-level Decode method, you can
99// more finely control how the Decoder behaves using the DecoderConfig
100// structure. The top-level Decode method is just a convenience that sets
101// up the most basic Decoder.
102type Decoder struct {
103 config *DecoderConfig
104}
105
106// Metadata contains information about decoding a structure that
107// is tedious or difficult to get otherwise.
108type Metadata struct {
109 // Keys are the keys of the structure which were successfully decoded
110 Keys []string
111
112 // Unused is a slice of keys that were found in the raw value but
113 // weren't decoded since there was no matching field in the result interface
114 Unused []string
115}
116
117// Decode takes an input structure and uses reflection to translate it to
118// the output structure. output must be a pointer to a map or struct.
119func Decode(input interface{}, output interface{}) error {
120 config := &DecoderConfig{
121 Metadata: nil,
122 Result: output,
123 }
124
125 decoder, err := NewDecoder(config)
126 if err != nil {
127 return err
128 }
129
130 return decoder.Decode(input)
131}
132
133// WeakDecode is the same as Decode but is shorthand to enable
134// WeaklyTypedInput. See DecoderConfig for more info.
135func WeakDecode(input, output interface{}) error {
136 config := &DecoderConfig{
137 Metadata: nil,
138 Result: output,
139 WeaklyTypedInput: true,
140 }
141
142 decoder, err := NewDecoder(config)
143 if err != nil {
144 return err
145 }
146
147 return decoder.Decode(input)
148}
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
184// NewDecoder returns a new decoder for the given configuration. Once
185// a decoder has been returned, the same configuration must not be used
186// again.
187func NewDecoder(config *DecoderConfig) (*Decoder, error) {
188 val := reflect.ValueOf(config.Result)
189 if val.Kind() != reflect.Ptr {
190 return nil, errors.New("result must be a pointer")
191 }
192
193 val = val.Elem()
194 if !val.CanAddr() {
195 return nil, errors.New("result must be addressable (a pointer)")
196 }
197
198 if config.Metadata != nil {
199 if config.Metadata.Keys == nil {
200 config.Metadata.Keys = make([]string, 0)
201 }
202
203 if config.Metadata.Unused == nil {
204 config.Metadata.Unused = make([]string, 0)
205 }
206 }
207
208 if config.TagName == "" {
209 config.TagName = "mapstructure"
210 }
211
212 result := &Decoder{
213 config: config,
214 }
215
216 return result, nil
217}
218
219// Decode decodes the given raw interface to the target pointer specified
220// by the configuration.
221func (d *Decoder) Decode(input interface{}) error {
222 return d.decode("", input, reflect.ValueOf(d.config.Result).Elem())
223}
224
225// Decodes an unknown data type into a specific reflection value.
226func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) error {
227 if input == nil {
228 // If the data is nil, then we don't set anything, unless ZeroFields is set
229 // to true.
230 if d.config.ZeroFields {
231 outVal.Set(reflect.Zero(outVal.Type()))
232
233 if d.config.Metadata != nil && name != "" {
234 d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
235 }
236 }
237 return nil
238 }
239
240 inputVal := reflect.ValueOf(input)
241 if !inputVal.IsValid() {
242 // If the input value is invalid, then we just set the value
243 // to be the zero value.
244 outVal.Set(reflect.Zero(outVal.Type()))
245 if d.config.Metadata != nil && name != "" {
246 d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
247 }
248 return nil
249 }
250
251 if d.config.DecodeHook != nil {
252 // We have a DecodeHook, so let's pre-process the input.
253 var err error
254 input, err = DecodeHookExec(
255 d.config.DecodeHook,
256 inputVal.Type(), outVal.Type(), input)
257 if err != nil {
258 return fmt.Errorf("error decoding '%s': %s", name, err)
259 }
260 }
261
262 var err error
263 inputKind := getKind(outVal)
264 switch inputKind {
265 case reflect.Bool:
266 err = d.decodeBool(name, input, outVal)
267 case reflect.Interface:
268 err = d.decodeBasic(name, input, outVal)
269 case reflect.String:
270 err = d.decodeString(name, input, outVal)
271 case reflect.Int:
272 err = d.decodeInt(name, input, outVal)
273 case reflect.Uint:
274 err = d.decodeUint(name, input, outVal)
275 case reflect.Float32:
276 err = d.decodeFloat(name, input, outVal)
277 case reflect.Struct:
278 err = d.decodeStruct(name, input, outVal)
279 case reflect.Map:
280 err = d.decodeMap(name, input, outVal)
281 case reflect.Ptr:
282 err = d.decodePtr(name, input, outVal)
283 case reflect.Slice:
284 err = d.decodeSlice(name, input, outVal)
285 case reflect.Array:
286 err = d.decodeArray(name, input, outVal)
287 case reflect.Func:
288 err = d.decodeFunc(name, input, outVal)
289 default:
290 // If we reached this point then we weren't able to decode it
291 return fmt.Errorf("%s: unsupported type: %s", name, inputKind)
292 }
293
294 // If we reached here, then we successfully decoded SOMETHING, so
295 // mark the key as used if we're tracking metainput.
296 if d.config.Metadata != nil && name != "" {
297 d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
298 }
299
300 return err
301}
302
303// This decodes a basic type (bool, int, string, etc.) and sets the
304// value to "data" of that type.
305func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error {
306 if val.IsValid() && val.Elem().IsValid() {
307 return d.decode(name, data, val.Elem())
308 }
309 dataVal := reflect.ValueOf(data)
310 if !dataVal.IsValid() {
311 dataVal = reflect.Zero(val.Type())
312 }
313
314 dataValType := dataVal.Type()
315 if !dataValType.AssignableTo(val.Type()) {
316 return fmt.Errorf(
317 "'%s' expected type '%s', got '%s'",
318 name, val.Type(), dataValType)
319 }
320
321 val.Set(dataVal)
322 return nil
323}
324
325func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) error {
326 dataVal := reflect.ValueOf(data)
327 dataKind := getKind(dataVal)
328
329 converted := true
330 switch {
331 case dataKind == reflect.String:
332 val.SetString(dataVal.String())
333 case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
334 if dataVal.Bool() {
335 val.SetString("1")
336 } else {
337 val.SetString("0")
338 }
339 case dataKind == reflect.Int && d.config.WeaklyTypedInput:
340 val.SetString(strconv.FormatInt(dataVal.Int(), 10))
341 case dataKind == reflect.Uint && d.config.WeaklyTypedInput:
342 val.SetString(strconv.FormatUint(dataVal.Uint(), 10))
343 case dataKind == reflect.Float32 && d.config.WeaklyTypedInput:
344 val.SetString(strconv.FormatFloat(dataVal.Float(), 'f', -1, 64))
345 case dataKind == reflect.Slice && d.config.WeaklyTypedInput,
346 dataKind == reflect.Array && d.config.WeaklyTypedInput:
347 dataType := dataVal.Type()
348 elemKind := dataType.Elem().Kind()
349 switch elemKind {
350 case reflect.Uint8:
351 var uints []uint8
352 if dataKind == reflect.Array {
353 uints = make([]uint8, dataVal.Len(), dataVal.Len())
354 for i := range uints {
355 uints[i] = dataVal.Index(i).Interface().(uint8)
356 }
357 } else {
358 uints = dataVal.Interface().([]uint8)
359 }
360 val.SetString(string(uints))
361 default:
362 converted = false
363 }
364 default:
365 converted = false
366 }
367
368 if !converted {
369 return fmt.Errorf(
370 "'%s' expected type '%s', got unconvertible type '%s'",
371 name, val.Type(), dataVal.Type())
372 }
373
374 return nil
375}
376
377func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) error {
378 dataVal := reflect.ValueOf(data)
379 dataKind := getKind(dataVal)
380 dataType := dataVal.Type()
381
382 switch {
383 case dataKind == reflect.Int:
384 val.SetInt(dataVal.Int())
385 case dataKind == reflect.Uint:
386 val.SetInt(int64(dataVal.Uint()))
387 case dataKind == reflect.Float32:
388 val.SetInt(int64(dataVal.Float()))
389 case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
390 if dataVal.Bool() {
391 val.SetInt(1)
392 } else {
393 val.SetInt(0)
394 }
395 case dataKind == reflect.String && d.config.WeaklyTypedInput:
396 i, err := strconv.ParseInt(dataVal.String(), 0, val.Type().Bits())
397 if err == nil {
398 val.SetInt(i)
399 } else {
400 return fmt.Errorf("cannot parse '%s' as int: %s", name, err)
401 }
402 case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
403 jn := data.(json.Number)
404 i, err := jn.Int64()
405 if err != nil {
406 return fmt.Errorf(
407 "error decoding json.Number into %s: %s", name, err)
408 }
409 val.SetInt(i)
410 default:
411 return fmt.Errorf(
412 "'%s' expected type '%s', got unconvertible type '%s'",
413 name, val.Type(), dataVal.Type())
414 }
415
416 return nil
417}
418
419func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) error {
420 dataVal := reflect.ValueOf(data)
421 dataKind := getKind(dataVal)
422
423 switch {
424 case dataKind == reflect.Int:
425 i := dataVal.Int()
426 if i < 0 && !d.config.WeaklyTypedInput {
427 return fmt.Errorf("cannot parse '%s', %d overflows uint",
428 name, i)
429 }
430 val.SetUint(uint64(i))
431 case dataKind == reflect.Uint:
432 val.SetUint(dataVal.Uint())
433 case dataKind == reflect.Float32:
434 f := dataVal.Float()
435 if f < 0 && !d.config.WeaklyTypedInput {
436 return fmt.Errorf("cannot parse '%s', %f overflows uint",
437 name, f)
438 }
439 val.SetUint(uint64(f))
440 case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
441 if dataVal.Bool() {
442 val.SetUint(1)
443 } else {
444 val.SetUint(0)
445 }
446 case dataKind == reflect.String && d.config.WeaklyTypedInput:
447 i, err := strconv.ParseUint(dataVal.String(), 0, val.Type().Bits())
448 if err == nil {
449 val.SetUint(i)
450 } else {
451 return fmt.Errorf("cannot parse '%s' as uint: %s", name, err)
452 }
453 default:
454 return fmt.Errorf(
455 "'%s' expected type '%s', got unconvertible type '%s'",
456 name, val.Type(), dataVal.Type())
457 }
458
459 return nil
460}
461
462func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) error {
463 dataVal := reflect.ValueOf(data)
464 dataKind := getKind(dataVal)
465
466 switch {
467 case dataKind == reflect.Bool:
468 val.SetBool(dataVal.Bool())
469 case dataKind == reflect.Int && d.config.WeaklyTypedInput:
470 val.SetBool(dataVal.Int() != 0)
471 case dataKind == reflect.Uint && d.config.WeaklyTypedInput:
472 val.SetBool(dataVal.Uint() != 0)
473 case dataKind == reflect.Float32 && d.config.WeaklyTypedInput:
474 val.SetBool(dataVal.Float() != 0)
475 case dataKind == reflect.String && d.config.WeaklyTypedInput:
476 b, err := strconv.ParseBool(dataVal.String())
477 if err == nil {
478 val.SetBool(b)
479 } else if dataVal.String() == "" {
480 val.SetBool(false)
481 } else {
482 return fmt.Errorf("cannot parse '%s' as bool: %s", name, err)
483 }
484 default:
485 return fmt.Errorf(
486 "'%s' expected type '%s', got unconvertible type '%s'",
487 name, val.Type(), dataVal.Type())
488 }
489
490 return nil
491}
492
493func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) error {
494 dataVal := reflect.ValueOf(data)
495 dataKind := getKind(dataVal)
496 dataType := dataVal.Type()
497
498 switch {
499 case dataKind == reflect.Int:
500 val.SetFloat(float64(dataVal.Int()))
501 case dataKind == reflect.Uint:
502 val.SetFloat(float64(dataVal.Uint()))
503 case dataKind == reflect.Float32:
504 val.SetFloat(dataVal.Float())
505 case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
506 if dataVal.Bool() {
507 val.SetFloat(1)
508 } else {
509 val.SetFloat(0)
510 }
511 case dataKind == reflect.String && d.config.WeaklyTypedInput:
512 f, err := strconv.ParseFloat(dataVal.String(), val.Type().Bits())
513 if err == nil {
514 val.SetFloat(f)
515 } else {
516 return fmt.Errorf("cannot parse '%s' as float: %s", name, err)
517 }
518 case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
519 jn := data.(json.Number)
520 i, err := jn.Float64()
521 if err != nil {
522 return fmt.Errorf(
523 "error decoding json.Number into %s: %s", name, err)
524 }
525 val.SetFloat(i)
526 default:
527 return fmt.Errorf(
528 "'%s' expected type '%s', got unconvertible type '%s'",
529 name, val.Type(), dataVal.Type())
530 }
531
532 return nil
533}
534
535func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) error {
536 valType := val.Type()
537 valKeyType := valType.Key()
538 valElemType := valType.Elem()
539
540 // By default we overwrite keys in the current map
541 valMap := val
542
543 // If the map is nil or we're purposely zeroing fields, make a new map
544 if valMap.IsNil() || d.config.ZeroFields {
545 // Make a new map to hold our result
546 mapType := reflect.MapOf(valKeyType, valElemType)
547 valMap = reflect.MakeMap(mapType)
548 }
549
550 // Check input type and based on the input type jump to the proper func
551 dataVal := reflect.Indirect(reflect.ValueOf(data))
552 switch dataVal.Kind() {
553 case reflect.Map:
554 return d.decodeMapFromMap(name, dataVal, val, valMap)
555
556 case reflect.Struct:
557 return d.decodeMapFromStruct(name, dataVal, val, valMap)
558
559 case reflect.Array, reflect.Slice:
560 if d.config.WeaklyTypedInput {
561 return d.decodeMapFromSlice(name, dataVal, val, valMap)
562 }
563
564 fallthrough
565
566 default:
567 return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind())
568 }
569}
570
571func (d *Decoder) decodeMapFromSlice(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {
572 // Special case for BC reasons (covered by tests)
573 if dataVal.Len() == 0 {
574 val.Set(valMap)
575 return nil
576 }
577
578 for i := 0; i < dataVal.Len(); i++ {
579 err := d.decode(
580 fmt.Sprintf("%s[%d]", name, i),
581 dataVal.Index(i).Interface(), val)
582 if err != nil {
583 return err
584 }
585 }
586
587 return nil
588}
589
590func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {
591 valType := val.Type()
592 valKeyType := valType.Key()
593 valElemType := valType.Elem()
594
595 // Accumulate errors
596 errors := make([]string, 0)
597
598 for _, k := range dataVal.MapKeys() {
599 fieldName := fmt.Sprintf("%s[%s]", name, k)
600
601 // First decode the key into the proper type
602 currentKey := reflect.Indirect(reflect.New(valKeyType))
603 if err := d.decode(fieldName, k.Interface(), currentKey); err != nil {
604 errors = appendErrors(errors, err)
605 continue
606 }
607
608 // Next decode the data into the proper type
609 v := dataVal.MapIndex(k).Interface()
610 currentVal := reflect.Indirect(reflect.New(valElemType))
611 if err := d.decode(fieldName, v, currentVal); err != nil {
612 errors = appendErrors(errors, err)
613 continue
614 }
615
616 valMap.SetMapIndex(currentKey, currentVal)
617 }
618
619 // Set the built up map to the value
620 val.Set(valMap)
621
622 // If we had errors, return those
623 if len(errors) > 0 {
624 return &Error{errors}
625 }
626
627 return nil
628}
629
630func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {
631 typ := dataVal.Type()
632 for i := 0; i < typ.NumField(); i++ {
633 // Get the StructField first since this is a cheap operation. If the
634 // field is unexported, then ignore it.
635 f := typ.Field(i)
636 if f.PkgPath != "" {
637 continue
638 }
639
640 // Next get the actual value of this field and verify it is assignable
641 // to the map value.
642 v := dataVal.Field(i)
643 if !v.Type().AssignableTo(valMap.Type().Elem()) {
644 return fmt.Errorf("cannot assign type '%s' to map value field of type '%s'", v.Type(), valMap.Type().Elem())
645 }
646
647 tagValue := f.Tag.Get(d.config.TagName)
648 tagParts := strings.Split(tagValue, ",")
649
650 // Determine the name of the key in the map
651 keyName := f.Name
652 if tagParts[0] != "" {
653 if tagParts[0] == "-" {
654 continue
655 }
656 keyName = tagParts[0]
657 }
658
659 // If "squash" is specified in the tag, we squash the field down.
660 squash := false
661 for _, tag := range tagParts[1:] {
662 if tag == "squash" {
663 squash = true
664 break
665 }
666 }
667 if squash && v.Kind() != reflect.Struct {
668 return fmt.Errorf("cannot squash non-struct type '%s'", v.Type())
669 }
670
671 switch v.Kind() {
672 // this is an embedded struct, so handle it differently
673 case reflect.Struct:
674 x := reflect.New(v.Type())
675 x.Elem().Set(v)
676
677 vType := valMap.Type()
678 vKeyType := vType.Key()
679 vElemType := vType.Elem()
680 mType := reflect.MapOf(vKeyType, vElemType)
681 vMap := reflect.MakeMap(mType)
682
683 err := d.decode(keyName, x.Interface(), vMap)
684 if err != nil {
685 return err
686 }
687
688 if squash {
689 for _, k := range vMap.MapKeys() {
690 valMap.SetMapIndex(k, vMap.MapIndex(k))
691 }
692 } else {
693 valMap.SetMapIndex(reflect.ValueOf(keyName), vMap)
694 }
695
696 default:
697 valMap.SetMapIndex(reflect.ValueOf(keyName), v)
698 }
699 }
700
701 if val.CanAddr() {
702 val.Set(valMap)
703 }
704
705 return nil
706}
707
708func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) error {
709 // Create an element of the concrete (non pointer) type and decode
710 // into that. Then set the value of the pointer to this type.
711 valType := val.Type()
712 valElemType := valType.Elem()
713
714 if val.CanSet() {
715 realVal := val
716 if realVal.IsNil() || d.config.ZeroFields {
717 realVal = reflect.New(valElemType)
718 }
719
720 if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil {
721 return err
722 }
723
724 val.Set(realVal)
725 } else {
726 if err := d.decode(name, data, reflect.Indirect(val)); err != nil {
727 return err
728 }
729 }
730 return nil
731}
732
733func (d *Decoder) decodeFunc(name string, data interface{}, val reflect.Value) error {
734 // Create an element of the concrete (non pointer) type and decode
735 // into that. Then set the value of the pointer to this type.
736 dataVal := reflect.Indirect(reflect.ValueOf(data))
737 if val.Type() != dataVal.Type() {
738 return fmt.Errorf(
739 "'%s' expected type '%s', got unconvertible type '%s'",
740 name, val.Type(), dataVal.Type())
741 }
742 val.Set(dataVal)
743 return nil
744}
745
746func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error {
747 dataVal := reflect.Indirect(reflect.ValueOf(data))
748 dataValKind := dataVal.Kind()
749 valType := val.Type()
750 valElemType := valType.Elem()
751 sliceType := reflect.SliceOf(valElemType)
752
753 valSlice := val
754 if valSlice.IsNil() || d.config.ZeroFields {
755 // Check input type
756 if dataValKind != reflect.Array && dataValKind != reflect.Slice {
757 if d.config.WeaklyTypedInput {
758 switch {
759 // Empty maps turn into empty slices
760 case dataValKind == reflect.Map:
761 if dataVal.Len() == 0 {
762 val.Set(reflect.MakeSlice(sliceType, 0, 0))
763 return nil
764 }
765 // Create slice of maps of other sizes
766 return d.decodeSlice(name, []interface{}{data}, val)
767
768 case dataValKind == reflect.String && valElemType.Kind() == reflect.Uint8:
769 return d.decodeSlice(name, []byte(dataVal.String()), val)
770 // All other types we try to convert to the slice type
771 // and "lift" it into it. i.e. a string becomes a string slice.
772 default:
773 // Just re-try this function with data as a slice.
774 return d.decodeSlice(name, []interface{}{data}, val)
775 }
776 }
777 return fmt.Errorf(
778 "'%s': source data must be an array or slice, got %s", name, dataValKind)
779
780 }
781
782 // Make a new slice to hold our result, same size as the original data.
783 valSlice = reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len())
784 }
785
786 // Accumulate any errors
787 errors := make([]string, 0)
788
789 for i := 0; i < dataVal.Len(); i++ {
790 currentData := dataVal.Index(i).Interface()
791 for valSlice.Len() <= i {
792 valSlice = reflect.Append(valSlice, reflect.Zero(valElemType))
793 }
794 currentField := valSlice.Index(i)
795
796 fieldName := fmt.Sprintf("%s[%d]", name, i)
797 if err := d.decode(fieldName, currentData, currentField); err != nil {
798 errors = appendErrors(errors, err)
799 }
800 }
801
802 // Finally, set the value to the slice we built up
803 val.Set(valSlice)
804
805 // If there were errors, we return those
806 if len(errors) > 0 {
807 return &Error{errors}
808 }
809
810 return nil
811}
812
813func (d *Decoder) decodeArray(name string, data interface{}, val reflect.Value) error {
814 dataVal := reflect.Indirect(reflect.ValueOf(data))
815 dataValKind := dataVal.Kind()
816 valType := val.Type()
817 valElemType := valType.Elem()
818 arrayType := reflect.ArrayOf(valType.Len(), valElemType)
819
820 valArray := val
821
822 if valArray.Interface() == reflect.Zero(valArray.Type()).Interface() || d.config.ZeroFields {
823 // Check input type
824 if dataValKind != reflect.Array && dataValKind != reflect.Slice {
825 if d.config.WeaklyTypedInput {
826 switch {
827 // Empty maps turn into empty arrays
828 case dataValKind == reflect.Map:
829 if dataVal.Len() == 0 {
830 val.Set(reflect.Zero(arrayType))
831 return nil
832 }
833
834 // All other types we try to convert to the array type
835 // and "lift" it into it. i.e. a string becomes a string array.
836 default:
837 // Just re-try this function with data as a slice.
838 return d.decodeArray(name, []interface{}{data}, val)
839 }
840 }
841
842 return fmt.Errorf(
843 "'%s': source data must be an array or slice, got %s", name, dataValKind)
844
845 }
846 if dataVal.Len() > arrayType.Len() {
847 return fmt.Errorf(
848 "'%s': expected source data to have length less or equal to %d, got %d", name, arrayType.Len(), dataVal.Len())
849
850 }
851
852 // Make a new array to hold our result, same size as the original data.
853 valArray = reflect.New(arrayType).Elem()
854 }
855
856 // Accumulate any errors
857 errors := make([]string, 0)
858
859 for i := 0; i < dataVal.Len(); i++ {
860 currentData := dataVal.Index(i).Interface()
861 currentField := valArray.Index(i)
862
863 fieldName := fmt.Sprintf("%s[%d]", name, i)
864 if err := d.decode(fieldName, currentData, currentField); err != nil {
865 errors = appendErrors(errors, err)
866 }
867 }
868
869 // Finally, set the value to the array we built up
870 val.Set(valArray)
871
872 // If there were errors, we return those
873 if len(errors) > 0 {
874 return &Error{errors}
875 }
876
877 return nil
878}
879
880func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) error {
881 dataVal := reflect.Indirect(reflect.ValueOf(data))
882
883 // If the type of the value to write to and the data match directly,
884 // then we just set it directly instead of recursing into the structure.
885 if dataVal.Type() == val.Type() {
886 val.Set(dataVal)
887 return nil
888 }
889
890 dataValKind := dataVal.Kind()
891 if dataValKind != reflect.Map {
892 return fmt.Errorf("'%s' expected a map, got '%s'", name, dataValKind)
893 }
894
895 dataValType := dataVal.Type()
896 if kind := dataValType.Key().Kind(); kind != reflect.String && kind != reflect.Interface {
897 return fmt.Errorf(
898 "'%s' needs a map with string keys, has '%s' keys",
899 name, dataValType.Key().Kind())
900 }
901
902 dataValKeys := make(map[reflect.Value]struct{})
903 dataValKeysUnused := make(map[interface{}]struct{})
904 for _, dataValKey := range dataVal.MapKeys() {
905 dataValKeys[dataValKey] = struct{}{}
906 dataValKeysUnused[dataValKey.Interface()] = struct{}{}
907 }
908
909 errors := make([]string, 0)
910
911 // This slice will keep track of all the structs we'll be decoding.
912 // There can be more than one struct if there are embedded structs
913 // that are squashed.
914 structs := make([]reflect.Value, 1, 5)
915 structs[0] = val
916
917 // Compile the list of all the fields that we're going to be decoding
918 // from all the structs.
919 type field struct {
920 field reflect.StructField
921 val reflect.Value
922 }
923 fields := []field{}
924 for len(structs) > 0 {
925 structVal := structs[0]
926 structs = structs[1:]
927
928 structType := structVal.Type()
929
930 for i := 0; i < structType.NumField(); i++ {
931 fieldType := structType.Field(i)
932 fieldKind := fieldType.Type.Kind()
933
934 // If "squash" is specified in the tag, we squash the field down.
935 squash := false
936 tagParts := strings.Split(fieldType.Tag.Get(d.config.TagName), ",")
937 for _, tag := range tagParts[1:] {
938 if tag == "squash" {
939 squash = true
940 break
941 }
942 }
943
944 if squash {
945 if fieldKind != reflect.Struct {
946 errors = appendErrors(errors,
947 fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldKind))
948 } else {
949 structs = append(structs, structVal.FieldByName(fieldType.Name))
950 }
951 continue
952 }
953
954 // Normal struct field, store it away
955 fields = append(fields, field{fieldType, structVal.Field(i)})
956 }
957 }
958
959 // for fieldType, field := range fields {
960 for _, f := range fields {
961 field, fieldValue := f.field, f.val
962 fieldName := field.Name
963
964 tagValue := field.Tag.Get(d.config.TagName)
965 tagValue = strings.SplitN(tagValue, ",", 2)[0]
966 if tagValue != "" {
967 fieldName = tagValue
968 }
969
970 rawMapKey := reflect.ValueOf(fieldName)
971 rawMapVal := dataVal.MapIndex(rawMapKey)
972 if !rawMapVal.IsValid() {
973 // Do a slower search by iterating over each key and
974 // doing case-insensitive search.
975 for dataValKey := range dataValKeys {
976 mK, ok := dataValKey.Interface().(string)
977 if !ok {
978 // Not a string key
979 continue
980 }
981
982 if strings.EqualFold(mK, fieldName) {
983 rawMapKey = dataValKey
984 rawMapVal = dataVal.MapIndex(dataValKey)
985 break
986 }
987 }
988
989 if !rawMapVal.IsValid() {
990 // There was no matching key in the map for the value in
991 // the struct. Just ignore.
992 continue
993 }
994 }
995
996 // Delete the key we're using from the unused map so we stop tracking
997 delete(dataValKeysUnused, rawMapKey.Interface())
998
999 if !fieldValue.IsValid() {
1000 // This should never happen
1001 panic("field is not valid")
1002 }
1003
1004 // If we can't set the field, then it is unexported or something,
1005 // and we just continue onwards.
1006 if !fieldValue.CanSet() {
1007 continue
1008 }
1009
1010 // If the name is empty string, then we're at the root, and we
1011 // don't dot-join the fields.
1012 if name != "" {
1013 fieldName = fmt.Sprintf("%s.%s", name, fieldName)
1014 }
1015
1016 if err := d.decode(fieldName, rawMapVal.Interface(), fieldValue); err != nil {
1017 errors = appendErrors(errors, err)
1018 }
1019 }
1020
1021 if d.config.ErrorUnused && len(dataValKeysUnused) > 0 {
1022 keys := make([]string, 0, len(dataValKeysUnused))
1023 for rawKey := range dataValKeysUnused {
1024 keys = append(keys, rawKey.(string))
1025 }
1026 sort.Strings(keys)
1027
1028 err := fmt.Errorf("'%s' has invalid keys: %s", name, strings.Join(keys, ", "))
1029 errors = appendErrors(errors, err)
1030 }
1031
1032 if len(errors) > 0 {
1033 return &Error{errors}
1034 }
1035
1036 // Add the unused keys to the list of unused keys if we're tracking metadata
1037 if d.config.Metadata != nil {
1038 for rawKey := range dataValKeysUnused {
1039 key := rawKey.(string)
1040 if name != "" {
1041 key = fmt.Sprintf("%s.%s", name, key)
1042 }
1043
1044 d.config.Metadata.Unused = append(d.config.Metadata.Unused, key)
1045 }
1046 }
1047
1048 return nil
1049}
1050
1051func getKind(val reflect.Value) reflect.Kind {
1052 kind := val.Kind()
1053
1054 switch {
1055 case kind >= reflect.Int && kind <= reflect.Int64:
1056 return reflect.Int
1057 case kind >= reflect.Uint && kind <= reflect.Uint64:
1058 return reflect.Uint
1059 case kind >= reflect.Float32 && kind <= reflect.Float64:
1060 return reflect.Float32
1061 default:
1062 return kind
1063 }
1064}