blob: 95eb686565fe699fcc2026fdd017884501c5c83d [file] [log] [blame]
khenaidooac637102019-01-14 15:44:34 -05001// 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 var inputVal reflect.Value
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 }
248 return nil
249 }
250
251 if !inputVal.IsValid() {
252 // If the input value is invalid, then we just set the value
253 // to be the zero value.
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 }
258 return nil
259 }
260
261 if d.config.DecodeHook != nil {
262 // We have a DecodeHook, so let's pre-process the input.
263 var err error
264 input, err = DecodeHookExec(
265 d.config.DecodeHook,
266 inputVal.Type(), outVal.Type(), input)
267 if err != nil {
268 return fmt.Errorf("error decoding '%s': %s", name, err)
269 }
270 }
271
272 var err error
273 outputKind := getKind(outVal)
274 switch outputKind {
275 case reflect.Bool:
276 err = d.decodeBool(name, input, outVal)
277 case reflect.Interface:
278 err = d.decodeBasic(name, input, outVal)
279 case reflect.String:
280 err = d.decodeString(name, input, outVal)
281 case reflect.Int:
282 err = d.decodeInt(name, input, outVal)
283 case reflect.Uint:
284 err = d.decodeUint(name, input, outVal)
285 case reflect.Float32:
286 err = d.decodeFloat(name, input, outVal)
287 case reflect.Struct:
288 err = d.decodeStruct(name, input, outVal)
289 case reflect.Map:
290 err = d.decodeMap(name, input, outVal)
291 case reflect.Ptr:
292 err = d.decodePtr(name, input, outVal)
293 case reflect.Slice:
294 err = d.decodeSlice(name, input, outVal)
295 case reflect.Array:
296 err = d.decodeArray(name, input, outVal)
297 case reflect.Func:
298 err = d.decodeFunc(name, input, outVal)
299 default:
300 // If we reached this point then we weren't able to decode it
301 return fmt.Errorf("%s: unsupported type: %s", name, outputKind)
302 }
303
304 // If we reached here, then we successfully decoded SOMETHING, so
305 // mark the key as used if we're tracking metainput.
306 if d.config.Metadata != nil && name != "" {
307 d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
308 }
309
310 return err
311}
312
313// This decodes a basic type (bool, int, string, etc.) and sets the
314// value to "data" of that type.
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 dataVal := reflect.Indirect(reflect.ValueOf(data))
320 if !dataVal.IsValid() {
321 dataVal = reflect.Zero(val.Type())
322 }
323
324 dataValType := dataVal.Type()
325 if !dataValType.AssignableTo(val.Type()) {
326 return fmt.Errorf(
327 "'%s' expected type '%s', got '%s'",
328 name, val.Type(), dataValType)
329 }
330
331 val.Set(dataVal)
332 return nil
333}
334
335func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) error {
336 dataVal := reflect.Indirect(reflect.ValueOf(data))
337 dataKind := getKind(dataVal)
338
339 converted := true
340 switch {
341 case dataKind == reflect.String:
342 val.SetString(dataVal.String())
343 case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
344 if dataVal.Bool() {
345 val.SetString("1")
346 } else {
347 val.SetString("0")
348 }
349 case dataKind == reflect.Int && d.config.WeaklyTypedInput:
350 val.SetString(strconv.FormatInt(dataVal.Int(), 10))
351 case dataKind == reflect.Uint && d.config.WeaklyTypedInput:
352 val.SetString(strconv.FormatUint(dataVal.Uint(), 10))
353 case dataKind == reflect.Float32 && d.config.WeaklyTypedInput:
354 val.SetString(strconv.FormatFloat(dataVal.Float(), 'f', -1, 64))
355 case dataKind == reflect.Slice && d.config.WeaklyTypedInput,
356 dataKind == reflect.Array && d.config.WeaklyTypedInput:
357 dataType := dataVal.Type()
358 elemKind := dataType.Elem().Kind()
359 switch elemKind {
360 case reflect.Uint8:
361 var uints []uint8
362 if dataKind == reflect.Array {
363 uints = make([]uint8, dataVal.Len(), dataVal.Len())
364 for i := range uints {
365 uints[i] = dataVal.Index(i).Interface().(uint8)
366 }
367 } else {
368 uints = dataVal.Interface().([]uint8)
369 }
370 val.SetString(string(uints))
371 default:
372 converted = false
373 }
374 default:
375 converted = false
376 }
377
378 if !converted {
379 return fmt.Errorf(
380 "'%s' expected type '%s', got unconvertible type '%s'",
381 name, val.Type(), dataVal.Type())
382 }
383
384 return nil
385}
386
387func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) error {
388 dataVal := reflect.Indirect(reflect.ValueOf(data))
389 dataKind := getKind(dataVal)
390 dataType := dataVal.Type()
391
392 switch {
393 case dataKind == reflect.Int:
394 val.SetInt(dataVal.Int())
395 case dataKind == reflect.Uint:
396 val.SetInt(int64(dataVal.Uint()))
397 case dataKind == reflect.Float32:
398 val.SetInt(int64(dataVal.Float()))
399 case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
400 if dataVal.Bool() {
401 val.SetInt(1)
402 } else {
403 val.SetInt(0)
404 }
405 case dataKind == reflect.String && d.config.WeaklyTypedInput:
406 i, err := strconv.ParseInt(dataVal.String(), 0, val.Type().Bits())
407 if err == nil {
408 val.SetInt(i)
409 } else {
410 return fmt.Errorf("cannot parse '%s' as int: %s", name, err)
411 }
412 case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
413 jn := data.(json.Number)
414 i, err := jn.Int64()
415 if err != nil {
416 return fmt.Errorf(
417 "error decoding json.Number into %s: %s", name, err)
418 }
419 val.SetInt(i)
420 default:
421 return fmt.Errorf(
422 "'%s' expected type '%s', got unconvertible type '%s'",
423 name, val.Type(), dataVal.Type())
424 }
425
426 return nil
427}
428
429func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) error {
430 dataVal := reflect.Indirect(reflect.ValueOf(data))
431 dataKind := getKind(dataVal)
432
433 switch {
434 case dataKind == reflect.Int:
435 i := dataVal.Int()
436 if i < 0 && !d.config.WeaklyTypedInput {
437 return fmt.Errorf("cannot parse '%s', %d overflows uint",
438 name, i)
439 }
440 val.SetUint(uint64(i))
441 case dataKind == reflect.Uint:
442 val.SetUint(dataVal.Uint())
443 case dataKind == reflect.Float32:
444 f := dataVal.Float()
445 if f < 0 && !d.config.WeaklyTypedInput {
446 return fmt.Errorf("cannot parse '%s', %f overflows uint",
447 name, f)
448 }
449 val.SetUint(uint64(f))
450 case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
451 if dataVal.Bool() {
452 val.SetUint(1)
453 } else {
454 val.SetUint(0)
455 }
456 case dataKind == reflect.String && d.config.WeaklyTypedInput:
457 i, err := strconv.ParseUint(dataVal.String(), 0, val.Type().Bits())
458 if err == nil {
459 val.SetUint(i)
460 } else {
461 return fmt.Errorf("cannot parse '%s' as uint: %s", name, err)
462 }
463 default:
464 return fmt.Errorf(
465 "'%s' expected type '%s', got unconvertible type '%s'",
466 name, val.Type(), dataVal.Type())
467 }
468
469 return nil
470}
471
472func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) error {
473 dataVal := reflect.Indirect(reflect.ValueOf(data))
474 dataKind := getKind(dataVal)
475
476 switch {
477 case dataKind == reflect.Bool:
478 val.SetBool(dataVal.Bool())
479 case dataKind == reflect.Int && d.config.WeaklyTypedInput:
480 val.SetBool(dataVal.Int() != 0)
481 case dataKind == reflect.Uint && d.config.WeaklyTypedInput:
482 val.SetBool(dataVal.Uint() != 0)
483 case dataKind == reflect.Float32 && d.config.WeaklyTypedInput:
484 val.SetBool(dataVal.Float() != 0)
485 case dataKind == reflect.String && d.config.WeaklyTypedInput:
486 b, err := strconv.ParseBool(dataVal.String())
487 if err == nil {
488 val.SetBool(b)
489 } else if dataVal.String() == "" {
490 val.SetBool(false)
491 } else {
492 return fmt.Errorf("cannot parse '%s' as bool: %s", name, err)
493 }
494 default:
495 return fmt.Errorf(
496 "'%s' expected type '%s', got unconvertible type '%s'",
497 name, val.Type(), dataVal.Type())
498 }
499
500 return nil
501}
502
503func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) error {
504 dataVal := reflect.Indirect(reflect.ValueOf(data))
505 dataKind := getKind(dataVal)
506 dataType := dataVal.Type()
507
508 switch {
509 case dataKind == reflect.Int:
510 val.SetFloat(float64(dataVal.Int()))
511 case dataKind == reflect.Uint:
512 val.SetFloat(float64(dataVal.Uint()))
513 case dataKind == reflect.Float32:
514 val.SetFloat(dataVal.Float())
515 case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
516 if dataVal.Bool() {
517 val.SetFloat(1)
518 } else {
519 val.SetFloat(0)
520 }
521 case dataKind == reflect.String && d.config.WeaklyTypedInput:
522 f, err := strconv.ParseFloat(dataVal.String(), val.Type().Bits())
523 if err == nil {
524 val.SetFloat(f)
525 } else {
526 return fmt.Errorf("cannot parse '%s' as float: %s", name, err)
527 }
528 case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
529 jn := data.(json.Number)
530 i, err := jn.Float64()
531 if err != nil {
532 return fmt.Errorf(
533 "error decoding json.Number into %s: %s", name, err)
534 }
535 val.SetFloat(i)
536 default:
537 return fmt.Errorf(
538 "'%s' expected type '%s', got unconvertible type '%s'",
539 name, val.Type(), dataVal.Type())
540 }
541
542 return nil
543}
544
545func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) error {
546 valType := val.Type()
547 valKeyType := valType.Key()
548 valElemType := valType.Elem()
549
550 // By default we overwrite keys in the current map
551 valMap := val
552
553 // If the map is nil or we're purposely zeroing fields, make a new map
554 if valMap.IsNil() || d.config.ZeroFields {
555 // Make a new map to hold our result
556 mapType := reflect.MapOf(valKeyType, valElemType)
557 valMap = reflect.MakeMap(mapType)
558 }
559
560 // Check input type and based on the input type jump to the proper func
561 dataVal := reflect.Indirect(reflect.ValueOf(data))
562 switch dataVal.Kind() {
563 case reflect.Map:
564 return d.decodeMapFromMap(name, dataVal, val, valMap)
565
566 case reflect.Struct:
567 return d.decodeMapFromStruct(name, dataVal, val, valMap)
568
569 case reflect.Array, reflect.Slice:
570 if d.config.WeaklyTypedInput {
571 return d.decodeMapFromSlice(name, dataVal, val, valMap)
572 }
573
574 fallthrough
575
576 default:
577 return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind())
578 }
579}
580
581func (d *Decoder) decodeMapFromSlice(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {
582 // Special case for BC reasons (covered by tests)
583 if dataVal.Len() == 0 {
584 val.Set(valMap)
585 return nil
586 }
587
588 for i := 0; i < dataVal.Len(); i++ {
589 err := d.decode(
590 fmt.Sprintf("%s[%d]", name, i),
591 dataVal.Index(i).Interface(), val)
592 if err != nil {
593 return err
594 }
595 }
596
597 return nil
598}
599
600func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {
601 valType := val.Type()
602 valKeyType := valType.Key()
603 valElemType := valType.Elem()
604
605 // Accumulate errors
606 errors := make([]string, 0)
607
608 // If the input data is empty, then we just match what the input data is.
609 if dataVal.Len() == 0 {
610 if dataVal.IsNil() {
611 if !val.IsNil() {
612 val.Set(dataVal)
613 }
614 } else {
615 // Set to empty allocated value
616 val.Set(valMap)
617 }
618
619 return nil
620 }
621
622 for _, k := range dataVal.MapKeys() {
623 fieldName := fmt.Sprintf("%s[%s]", name, k)
624
625 // First decode the key into the proper type
626 currentKey := reflect.Indirect(reflect.New(valKeyType))
627 if err := d.decode(fieldName, k.Interface(), currentKey); err != nil {
628 errors = appendErrors(errors, err)
629 continue
630 }
631
632 // Next decode the data into the proper type
633 v := dataVal.MapIndex(k).Interface()
634 currentVal := reflect.Indirect(reflect.New(valElemType))
635 if err := d.decode(fieldName, v, currentVal); err != nil {
636 errors = appendErrors(errors, err)
637 continue
638 }
639
640 valMap.SetMapIndex(currentKey, currentVal)
641 }
642
643 // Set the built up map to the value
644 val.Set(valMap)
645
646 // If we had errors, return those
647 if len(errors) > 0 {
648 return &Error{errors}
649 }
650
651 return nil
652}
653
654func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {
655 typ := dataVal.Type()
656 for i := 0; i < typ.NumField(); i++ {
657 // Get the StructField first since this is a cheap operation. If the
658 // field is unexported, then ignore it.
659 f := typ.Field(i)
660 if f.PkgPath != "" {
661 continue
662 }
663
664 // Next get the actual value of this field and verify it is assignable
665 // to the map value.
666 v := dataVal.Field(i)
667 if !v.Type().AssignableTo(valMap.Type().Elem()) {
668 return fmt.Errorf("cannot assign type '%s' to map value field of type '%s'", v.Type(), valMap.Type().Elem())
669 }
670
671 tagValue := f.Tag.Get(d.config.TagName)
672 tagParts := strings.Split(tagValue, ",")
673
674 // Determine the name of the key in the map
675 keyName := f.Name
676 if tagParts[0] != "" {
677 if tagParts[0] == "-" {
678 continue
679 }
680 keyName = tagParts[0]
681 }
682
683 // If "squash" is specified in the tag, we squash the field down.
684 squash := false
685 for _, tag := range tagParts[1:] {
686 if tag == "squash" {
687 squash = true
688 break
689 }
690 }
691 if squash && v.Kind() != reflect.Struct {
692 return fmt.Errorf("cannot squash non-struct type '%s'", v.Type())
693 }
694
695 switch v.Kind() {
696 // this is an embedded struct, so handle it differently
697 case reflect.Struct:
698 x := reflect.New(v.Type())
699 x.Elem().Set(v)
700
701 vType := valMap.Type()
702 vKeyType := vType.Key()
703 vElemType := vType.Elem()
704 mType := reflect.MapOf(vKeyType, vElemType)
705 vMap := reflect.MakeMap(mType)
706
707 err := d.decode(keyName, x.Interface(), vMap)
708 if err != nil {
709 return err
710 }
711
712 if squash {
713 for _, k := range vMap.MapKeys() {
714 valMap.SetMapIndex(k, vMap.MapIndex(k))
715 }
716 } else {
717 valMap.SetMapIndex(reflect.ValueOf(keyName), vMap)
718 }
719
720 default:
721 valMap.SetMapIndex(reflect.ValueOf(keyName), v)
722 }
723 }
724
725 if val.CanAddr() {
726 val.Set(valMap)
727 }
728
729 return nil
730}
731
732func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) error {
733 // If the input data is nil, then we want to just set the output
734 // pointer to be nil as well.
735 isNil := data == nil
736 if !isNil {
737 switch v := reflect.Indirect(reflect.ValueOf(data)); v.Kind() {
738 case reflect.Chan,
739 reflect.Func,
740 reflect.Interface,
741 reflect.Map,
742 reflect.Ptr,
743 reflect.Slice:
744 isNil = v.IsNil()
745 }
746 }
747 if isNil {
748 if !val.IsNil() && val.CanSet() {
749 nilValue := reflect.New(val.Type()).Elem()
750 val.Set(nilValue)
751 }
752
753 return nil
754 }
755
756 // Create an element of the concrete (non pointer) type and decode
757 // into that. Then set the value of the pointer to this type.
758 valType := val.Type()
759 valElemType := valType.Elem()
760 if val.CanSet() {
761 realVal := val
762 if realVal.IsNil() || d.config.ZeroFields {
763 realVal = reflect.New(valElemType)
764 }
765
766 if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil {
767 return err
768 }
769
770 val.Set(realVal)
771 } else {
772 if err := d.decode(name, data, reflect.Indirect(val)); err != nil {
773 return err
774 }
775 }
776 return nil
777}
778
779func (d *Decoder) decodeFunc(name string, data interface{}, val reflect.Value) error {
780 // Create an element of the concrete (non pointer) type and decode
781 // into that. Then set the value of the pointer to this type.
782 dataVal := reflect.Indirect(reflect.ValueOf(data))
783 if val.Type() != dataVal.Type() {
784 return fmt.Errorf(
785 "'%s' expected type '%s', got unconvertible type '%s'",
786 name, val.Type(), dataVal.Type())
787 }
788 val.Set(dataVal)
789 return nil
790}
791
792func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error {
793 dataVal := reflect.Indirect(reflect.ValueOf(data))
794 dataValKind := dataVal.Kind()
795 valType := val.Type()
796 valElemType := valType.Elem()
797 sliceType := reflect.SliceOf(valElemType)
798
799 valSlice := val
800 if valSlice.IsNil() || d.config.ZeroFields {
801 if d.config.WeaklyTypedInput {
802 switch {
803 // Slice and array we use the normal logic
804 case dataValKind == reflect.Slice, dataValKind == reflect.Array:
805 break
806
807 // Empty maps turn into empty slices
808 case dataValKind == reflect.Map:
809 if dataVal.Len() == 0 {
810 val.Set(reflect.MakeSlice(sliceType, 0, 0))
811 return nil
812 }
813 // Create slice of maps of other sizes
814 return d.decodeSlice(name, []interface{}{data}, val)
815
816 case dataValKind == reflect.String && valElemType.Kind() == reflect.Uint8:
817 return d.decodeSlice(name, []byte(dataVal.String()), val)
818
819 // All other types we try to convert to the slice type
820 // and "lift" it into it. i.e. a string becomes a string slice.
821 default:
822 // Just re-try this function with data as a slice.
823 return d.decodeSlice(name, []interface{}{data}, val)
824 }
825 }
826
827 // Check input type
828 if dataValKind != reflect.Array && dataValKind != reflect.Slice {
829 return fmt.Errorf(
830 "'%s': source data must be an array or slice, got %s", name, dataValKind)
831
832 }
833
834 // If the input value is empty, then don't allocate since non-nil != nil
835 if dataVal.Len() == 0 {
836 return nil
837 }
838
839 // Make a new slice to hold our result, same size as the original data.
840 valSlice = reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len())
841 }
842
843 // Accumulate any errors
844 errors := make([]string, 0)
845
846 for i := 0; i < dataVal.Len(); i++ {
847 currentData := dataVal.Index(i).Interface()
848 for valSlice.Len() <= i {
849 valSlice = reflect.Append(valSlice, reflect.Zero(valElemType))
850 }
851 currentField := valSlice.Index(i)
852
853 fieldName := fmt.Sprintf("%s[%d]", name, i)
854 if err := d.decode(fieldName, currentData, currentField); err != nil {
855 errors = appendErrors(errors, err)
856 }
857 }
858
859 // Finally, set the value to the slice we built up
860 val.Set(valSlice)
861
862 // If there were errors, we return those
863 if len(errors) > 0 {
864 return &Error{errors}
865 }
866
867 return nil
868}
869
870func (d *Decoder) decodeArray(name string, data interface{}, val reflect.Value) error {
871 dataVal := reflect.Indirect(reflect.ValueOf(data))
872 dataValKind := dataVal.Kind()
873 valType := val.Type()
874 valElemType := valType.Elem()
875 arrayType := reflect.ArrayOf(valType.Len(), valElemType)
876
877 valArray := val
878
879 if valArray.Interface() == reflect.Zero(valArray.Type()).Interface() || d.config.ZeroFields {
880 // Check input type
881 if dataValKind != reflect.Array && dataValKind != reflect.Slice {
882 if d.config.WeaklyTypedInput {
883 switch {
884 // Empty maps turn into empty arrays
885 case dataValKind == reflect.Map:
886 if dataVal.Len() == 0 {
887 val.Set(reflect.Zero(arrayType))
888 return nil
889 }
890
891 // All other types we try to convert to the array type
892 // and "lift" it into it. i.e. a string becomes a string array.
893 default:
894 // Just re-try this function with data as a slice.
895 return d.decodeArray(name, []interface{}{data}, val)
896 }
897 }
898
899 return fmt.Errorf(
900 "'%s': source data must be an array or slice, got %s", name, dataValKind)
901
902 }
903 if dataVal.Len() > arrayType.Len() {
904 return fmt.Errorf(
905 "'%s': expected source data to have length less or equal to %d, got %d", name, arrayType.Len(), dataVal.Len())
906
907 }
908
909 // Make a new array to hold our result, same size as the original data.
910 valArray = reflect.New(arrayType).Elem()
911 }
912
913 // Accumulate any errors
914 errors := make([]string, 0)
915
916 for i := 0; i < dataVal.Len(); i++ {
917 currentData := dataVal.Index(i).Interface()
918 currentField := valArray.Index(i)
919
920 fieldName := fmt.Sprintf("%s[%d]", name, i)
921 if err := d.decode(fieldName, currentData, currentField); err != nil {
922 errors = appendErrors(errors, err)
923 }
924 }
925
926 // Finally, set the value to the array we built up
927 val.Set(valArray)
928
929 // If there were errors, we return those
930 if len(errors) > 0 {
931 return &Error{errors}
932 }
933
934 return nil
935}
936
937func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) error {
938 dataVal := reflect.Indirect(reflect.ValueOf(data))
939
940 // If the type of the value to write to and the data match directly,
941 // then we just set it directly instead of recursing into the structure.
942 if dataVal.Type() == val.Type() {
943 val.Set(dataVal)
944 return nil
945 }
946
947 dataValKind := dataVal.Kind()
948 switch dataValKind {
949 case reflect.Map:
950 return d.decodeStructFromMap(name, dataVal, val)
951
952 case reflect.Struct:
953 // Not the most efficient way to do this but we can optimize later if
954 // we want to. To convert from struct to struct we go to map first
955 // as an intermediary.
956 m := make(map[string]interface{})
957 mval := reflect.Indirect(reflect.ValueOf(&m))
958 if err := d.decodeMapFromStruct(name, dataVal, mval, mval); err != nil {
959 return err
960 }
961
962 result := d.decodeStructFromMap(name, mval, val)
963 return result
964
965 default:
966 return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind())
967 }
968}
969
970func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) error {
971 dataValType := dataVal.Type()
972 if kind := dataValType.Key().Kind(); kind != reflect.String && kind != reflect.Interface {
973 return fmt.Errorf(
974 "'%s' needs a map with string keys, has '%s' keys",
975 name, dataValType.Key().Kind())
976 }
977
978 dataValKeys := make(map[reflect.Value]struct{})
979 dataValKeysUnused := make(map[interface{}]struct{})
980 for _, dataValKey := range dataVal.MapKeys() {
981 dataValKeys[dataValKey] = struct{}{}
982 dataValKeysUnused[dataValKey.Interface()] = struct{}{}
983 }
984
985 errors := make([]string, 0)
986
987 // This slice will keep track of all the structs we'll be decoding.
988 // There can be more than one struct if there are embedded structs
989 // that are squashed.
990 structs := make([]reflect.Value, 1, 5)
991 structs[0] = val
992
993 // Compile the list of all the fields that we're going to be decoding
994 // from all the structs.
995 type field struct {
996 field reflect.StructField
997 val reflect.Value
998 }
999 fields := []field{}
1000 for len(structs) > 0 {
1001 structVal := structs[0]
1002 structs = structs[1:]
1003
1004 structType := structVal.Type()
1005
1006 for i := 0; i < structType.NumField(); i++ {
1007 fieldType := structType.Field(i)
1008 fieldKind := fieldType.Type.Kind()
1009
1010 // If "squash" is specified in the tag, we squash the field down.
1011 squash := false
1012 tagParts := strings.Split(fieldType.Tag.Get(d.config.TagName), ",")
1013 for _, tag := range tagParts[1:] {
1014 if tag == "squash" {
1015 squash = true
1016 break
1017 }
1018 }
1019
1020 if squash {
1021 if fieldKind != reflect.Struct {
1022 errors = appendErrors(errors,
1023 fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldKind))
1024 } else {
1025 structs = append(structs, structVal.FieldByName(fieldType.Name))
1026 }
1027 continue
1028 }
1029
1030 // Normal struct field, store it away
1031 fields = append(fields, field{fieldType, structVal.Field(i)})
1032 }
1033 }
1034
1035 // for fieldType, field := range fields {
1036 for _, f := range fields {
1037 field, fieldValue := f.field, f.val
1038 fieldName := field.Name
1039
1040 tagValue := field.Tag.Get(d.config.TagName)
1041 tagValue = strings.SplitN(tagValue, ",", 2)[0]
1042 if tagValue != "" {
1043 fieldName = tagValue
1044 }
1045
1046 rawMapKey := reflect.ValueOf(fieldName)
1047 rawMapVal := dataVal.MapIndex(rawMapKey)
1048 if !rawMapVal.IsValid() {
1049 // Do a slower search by iterating over each key and
1050 // doing case-insensitive search.
1051 for dataValKey := range dataValKeys {
1052 mK, ok := dataValKey.Interface().(string)
1053 if !ok {
1054 // Not a string key
1055 continue
1056 }
1057
1058 if strings.EqualFold(mK, fieldName) {
1059 rawMapKey = dataValKey
1060 rawMapVal = dataVal.MapIndex(dataValKey)
1061 break
1062 }
1063 }
1064
1065 if !rawMapVal.IsValid() {
1066 // There was no matching key in the map for the value in
1067 // the struct. Just ignore.
1068 continue
1069 }
1070 }
1071
1072 // Delete the key we're using from the unused map so we stop tracking
1073 delete(dataValKeysUnused, rawMapKey.Interface())
1074
1075 if !fieldValue.IsValid() {
1076 // This should never happen
1077 panic("field is not valid")
1078 }
1079
1080 // If we can't set the field, then it is unexported or something,
1081 // and we just continue onwards.
1082 if !fieldValue.CanSet() {
1083 continue
1084 }
1085
1086 // If the name is empty string, then we're at the root, and we
1087 // don't dot-join the fields.
1088 if name != "" {
1089 fieldName = fmt.Sprintf("%s.%s", name, fieldName)
1090 }
1091
1092 if err := d.decode(fieldName, rawMapVal.Interface(), fieldValue); err != nil {
1093 errors = appendErrors(errors, err)
1094 }
1095 }
1096
1097 if d.config.ErrorUnused && len(dataValKeysUnused) > 0 {
1098 keys := make([]string, 0, len(dataValKeysUnused))
1099 for rawKey := range dataValKeysUnused {
1100 keys = append(keys, rawKey.(string))
1101 }
1102 sort.Strings(keys)
1103
1104 err := fmt.Errorf("'%s' has invalid keys: %s", name, strings.Join(keys, ", "))
1105 errors = appendErrors(errors, err)
1106 }
1107
1108 if len(errors) > 0 {
1109 return &Error{errors}
1110 }
1111
1112 // Add the unused keys to the list of unused keys if we're tracking metadata
1113 if d.config.Metadata != nil {
1114 for rawKey := range dataValKeysUnused {
1115 key := rawKey.(string)
1116 if name != "" {
1117 key = fmt.Sprintf("%s.%s", name, key)
1118 }
1119
1120 d.config.Metadata.Unused = append(d.config.Metadata.Unused, key)
1121 }
1122 }
1123
1124 return nil
1125}
1126
1127func getKind(val reflect.Value) reflect.Kind {
1128 kind := val.Kind()
1129
1130 switch {
1131 case kind >= reflect.Int && kind <= reflect.Int64:
1132 return reflect.Int
1133 case kind >= reflect.Uint && kind <= reflect.Uint64:
1134 return reflect.Uint
1135 case kind >= reflect.Float32 && kind <= reflect.Float64:
1136 return reflect.Float32
1137 default:
1138 return kind
1139 }
1140}