blob: 256ee63fbf3eebacee7e5404c94310c8b099f4b9 [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 }
Stephane Barbarie260a5632019-02-26 16:12:49 -0500319
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
khenaidooac637102019-01-14 15:44:34 -0500329 if !dataVal.IsValid() {
330 dataVal = reflect.Zero(val.Type())
331 }
332
333 dataValType := dataVal.Type()
334 if !dataValType.AssignableTo(val.Type()) {
335 return fmt.Errorf(
336 "'%s' expected type '%s', got '%s'",
337 name, val.Type(), dataValType)
338 }
339
340 val.Set(dataVal)
341 return nil
342}
343
344func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) error {
345 dataVal := reflect.Indirect(reflect.ValueOf(data))
346 dataKind := getKind(dataVal)
347
348 converted := true
349 switch {
350 case dataKind == reflect.String:
351 val.SetString(dataVal.String())
352 case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
353 if dataVal.Bool() {
354 val.SetString("1")
355 } else {
356 val.SetString("0")
357 }
358 case dataKind == reflect.Int && d.config.WeaklyTypedInput:
359 val.SetString(strconv.FormatInt(dataVal.Int(), 10))
360 case dataKind == reflect.Uint && d.config.WeaklyTypedInput:
361 val.SetString(strconv.FormatUint(dataVal.Uint(), 10))
362 case dataKind == reflect.Float32 && d.config.WeaklyTypedInput:
363 val.SetString(strconv.FormatFloat(dataVal.Float(), 'f', -1, 64))
364 case dataKind == reflect.Slice && d.config.WeaklyTypedInput,
365 dataKind == reflect.Array && d.config.WeaklyTypedInput:
366 dataType := dataVal.Type()
367 elemKind := dataType.Elem().Kind()
368 switch elemKind {
369 case reflect.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))
380 default:
381 converted = false
382 }
383 default:
384 converted = false
385 }
386
387 if !converted {
388 return fmt.Errorf(
389 "'%s' expected type '%s', got unconvertible type '%s'",
390 name, val.Type(), dataVal.Type())
391 }
392
393 return nil
394}
395
396func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) error {
397 dataVal := reflect.Indirect(reflect.ValueOf(data))
398 dataKind := getKind(dataVal)
399 dataType := dataVal.Type()
400
401 switch {
402 case dataKind == reflect.Int:
403 val.SetInt(dataVal.Int())
404 case dataKind == reflect.Uint:
405 val.SetInt(int64(dataVal.Uint()))
406 case dataKind == reflect.Float32:
407 val.SetInt(int64(dataVal.Float()))
408 case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
409 if dataVal.Bool() {
410 val.SetInt(1)
411 } else {
412 val.SetInt(0)
413 }
414 case dataKind == reflect.String && d.config.WeaklyTypedInput:
415 i, err := strconv.ParseInt(dataVal.String(), 0, val.Type().Bits())
416 if err == nil {
417 val.SetInt(i)
418 } else {
419 return fmt.Errorf("cannot parse '%s' as int: %s", name, err)
420 }
421 case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
422 jn := data.(json.Number)
423 i, err := jn.Int64()
424 if err != nil {
425 return fmt.Errorf(
426 "error decoding json.Number into %s: %s", name, err)
427 }
428 val.SetInt(i)
429 default:
430 return fmt.Errorf(
431 "'%s' expected type '%s', got unconvertible type '%s'",
432 name, val.Type(), dataVal.Type())
433 }
434
435 return nil
436}
437
438func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) error {
439 dataVal := reflect.Indirect(reflect.ValueOf(data))
440 dataKind := getKind(dataVal)
441
442 switch {
443 case dataKind == reflect.Int:
444 i := dataVal.Int()
445 if i < 0 && !d.config.WeaklyTypedInput {
446 return fmt.Errorf("cannot parse '%s', %d overflows uint",
447 name, i)
448 }
449 val.SetUint(uint64(i))
450 case dataKind == reflect.Uint:
451 val.SetUint(dataVal.Uint())
452 case dataKind == reflect.Float32:
453 f := dataVal.Float()
454 if f < 0 && !d.config.WeaklyTypedInput {
455 return fmt.Errorf("cannot parse '%s', %f overflows uint",
456 name, f)
457 }
458 val.SetUint(uint64(f))
459 case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
460 if dataVal.Bool() {
461 val.SetUint(1)
462 } else {
463 val.SetUint(0)
464 }
465 case dataKind == reflect.String && d.config.WeaklyTypedInput:
466 i, err := strconv.ParseUint(dataVal.String(), 0, val.Type().Bits())
467 if err == nil {
468 val.SetUint(i)
469 } else {
470 return fmt.Errorf("cannot parse '%s' as uint: %s", name, err)
471 }
472 default:
473 return fmt.Errorf(
474 "'%s' expected type '%s', got unconvertible type '%s'",
475 name, val.Type(), dataVal.Type())
476 }
477
478 return nil
479}
480
481func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) error {
482 dataVal := reflect.Indirect(reflect.ValueOf(data))
483 dataKind := getKind(dataVal)
484
485 switch {
486 case dataKind == reflect.Bool:
487 val.SetBool(dataVal.Bool())
488 case dataKind == reflect.Int && d.config.WeaklyTypedInput:
489 val.SetBool(dataVal.Int() != 0)
490 case dataKind == reflect.Uint && d.config.WeaklyTypedInput:
491 val.SetBool(dataVal.Uint() != 0)
492 case dataKind == reflect.Float32 && d.config.WeaklyTypedInput:
493 val.SetBool(dataVal.Float() != 0)
494 case dataKind == reflect.String && d.config.WeaklyTypedInput:
495 b, err := strconv.ParseBool(dataVal.String())
496 if err == nil {
497 val.SetBool(b)
498 } else if dataVal.String() == "" {
499 val.SetBool(false)
500 } else {
501 return fmt.Errorf("cannot parse '%s' as bool: %s", name, err)
502 }
503 default:
504 return fmt.Errorf(
505 "'%s' expected type '%s', got unconvertible type '%s'",
506 name, val.Type(), dataVal.Type())
507 }
508
509 return nil
510}
511
512func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) error {
513 dataVal := reflect.Indirect(reflect.ValueOf(data))
514 dataKind := getKind(dataVal)
515 dataType := dataVal.Type()
516
517 switch {
518 case dataKind == reflect.Int:
519 val.SetFloat(float64(dataVal.Int()))
520 case dataKind == reflect.Uint:
521 val.SetFloat(float64(dataVal.Uint()))
522 case dataKind == reflect.Float32:
523 val.SetFloat(dataVal.Float())
524 case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
525 if dataVal.Bool() {
526 val.SetFloat(1)
527 } else {
528 val.SetFloat(0)
529 }
530 case dataKind == reflect.String && d.config.WeaklyTypedInput:
531 f, err := strconv.ParseFloat(dataVal.String(), val.Type().Bits())
532 if err == nil {
533 val.SetFloat(f)
534 } else {
535 return fmt.Errorf("cannot parse '%s' as float: %s", name, err)
536 }
537 case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
538 jn := data.(json.Number)
539 i, err := jn.Float64()
540 if err != nil {
541 return fmt.Errorf(
542 "error decoding json.Number into %s: %s", name, err)
543 }
544 val.SetFloat(i)
545 default:
546 return fmt.Errorf(
547 "'%s' expected type '%s', got unconvertible type '%s'",
548 name, val.Type(), dataVal.Type())
549 }
550
551 return nil
552}
553
554func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) error {
555 valType := val.Type()
556 valKeyType := valType.Key()
557 valElemType := valType.Elem()
558
559 // By default we overwrite keys in the current map
560 valMap := val
561
562 // If the map is nil or we're purposely zeroing fields, make a new map
563 if valMap.IsNil() || d.config.ZeroFields {
564 // Make a new map to hold our result
565 mapType := reflect.MapOf(valKeyType, valElemType)
566 valMap = reflect.MakeMap(mapType)
567 }
568
569 // Check input type and based on the input type jump to the proper func
570 dataVal := reflect.Indirect(reflect.ValueOf(data))
571 switch dataVal.Kind() {
572 case reflect.Map:
573 return d.decodeMapFromMap(name, dataVal, val, valMap)
574
575 case reflect.Struct:
576 return d.decodeMapFromStruct(name, dataVal, val, valMap)
577
578 case reflect.Array, reflect.Slice:
579 if d.config.WeaklyTypedInput {
580 return d.decodeMapFromSlice(name, dataVal, val, valMap)
581 }
582
583 fallthrough
584
585 default:
586 return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind())
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()
613
614 // Accumulate errors
615 errors := make([]string, 0)
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
631 for _, k := range dataVal.MapKeys() {
632 fieldName := fmt.Sprintf("%s[%s]", name, k)
633
634 // First decode the key into the proper type
635 currentKey := reflect.Indirect(reflect.New(valKeyType))
636 if err := d.decode(fieldName, k.Interface(), currentKey); err != nil {
637 errors = appendErrors(errors, err)
638 continue
639 }
640
641 // Next decode the data into the proper type
642 v := dataVal.MapIndex(k).Interface()
643 currentVal := reflect.Indirect(reflect.New(valElemType))
644 if err := d.decode(fieldName, v, currentVal); err != nil {
645 errors = appendErrors(errors, err)
646 continue
647 }
648
649 valMap.SetMapIndex(currentKey, currentVal)
650 }
651
652 // Set the built up map to the value
653 val.Set(valMap)
654
655 // If we had errors, return those
656 if len(errors) > 0 {
657 return &Error{errors}
658 }
659
660 return nil
661}
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
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
765 // Create an element of the concrete (non pointer) type and decode
766 // into that. Then set the value of the pointer to this type.
767 valType := val.Type()
768 valElemType := valType.Elem()
769 if val.CanSet() {
770 realVal := val
771 if realVal.IsNil() || d.config.ZeroFields {
772 realVal = reflect.New(valElemType)
773 }
774
775 if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil {
776 return err
777 }
778
779 val.Set(realVal)
780 } else {
781 if err := d.decode(name, data, reflect.Indirect(val)); err != nil {
782 return err
783 }
784 }
785 return nil
786}
787
788func (d *Decoder) decodeFunc(name string, data interface{}, val reflect.Value) error {
789 // Create an element of the concrete (non pointer) type and decode
790 // into that. Then set the value of the pointer to this type.
791 dataVal := reflect.Indirect(reflect.ValueOf(data))
792 if val.Type() != dataVal.Type() {
793 return fmt.Errorf(
794 "'%s' expected type '%s', got unconvertible type '%s'",
795 name, val.Type(), dataVal.Type())
796 }
797 val.Set(dataVal)
798 return nil
799}
800
801func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error {
802 dataVal := reflect.Indirect(reflect.ValueOf(data))
803 dataValKind := dataVal.Kind()
804 valType := val.Type()
805 valElemType := valType.Elem()
806 sliceType := reflect.SliceOf(valElemType)
807
808 valSlice := val
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 {
889 // Check input type
890 if dataValKind != reflect.Array && dataValKind != reflect.Slice {
891 if d.config.WeaklyTypedInput {
892 switch {
893 // Empty maps turn into empty arrays
894 case dataValKind == reflect.Map:
895 if dataVal.Len() == 0 {
896 val.Set(reflect.Zero(arrayType))
897 return nil
898 }
899
900 // All other types we try to convert to the array type
901 // and "lift" it into it. i.e. a string becomes a string array.
902 default:
903 // Just re-try this function with data as a slice.
904 return d.decodeArray(name, []interface{}{data}, val)
905 }
906 }
907
908 return fmt.Errorf(
909 "'%s': source data must be an array or slice, got %s", name, dataValKind)
910
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())
915
916 }
917
918 // Make a new array to hold our result, same size as the original data.
919 valArray = reflect.New(arrayType).Elem()
920 }
921
922 // Accumulate any errors
923 errors := make([]string, 0)
924
925 for i := 0; i < dataVal.Len(); i++ {
926 currentData := dataVal.Index(i).Interface()
927 currentField := valArray.Index(i)
928
929 fieldName := fmt.Sprintf("%s[%d]", name, i)
930 if err := d.decode(fieldName, currentData, currentField); err != nil {
931 errors = appendErrors(errors, err)
932 }
933 }
934
935 // Finally, set the value to the array we built up
936 val.Set(valArray)
937
938 // If there were errors, we return those
939 if len(errors) > 0 {
940 return &Error{errors}
941 }
942
943 return nil
944}
945
946func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) error {
947 dataVal := reflect.Indirect(reflect.ValueOf(data))
948
949 // If the type of the value to write to and the data match directly,
950 // then we just set it directly instead of recursing into the structure.
951 if dataVal.Type() == val.Type() {
952 val.Set(dataVal)
953 return nil
954 }
955
956 dataValKind := dataVal.Kind()
957 switch 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())
976 }
977}
978
979func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) error {
980 dataValType := dataVal.Type()
981 if kind := dataValType.Key().Kind(); kind != reflect.String && kind != reflect.Interface {
982 return fmt.Errorf(
983 "'%s' needs a map with string keys, has '%s' keys",
984 name, dataValType.Key().Kind())
985 }
986
987 dataValKeys := make(map[reflect.Value]struct{})
988 dataValKeysUnused := make(map[interface{}]struct{})
989 for _, dataValKey := range dataVal.MapKeys() {
990 dataValKeys[dataValKey] = struct{}{}
991 dataValKeysUnused[dataValKey.Interface()] = struct{}{}
992 }
993
994 errors := make([]string, 0)
995
996 // This slice will keep track of all the structs we'll be decoding.
997 // There can be more than one struct if there are embedded structs
998 // that are squashed.
999 structs := make([]reflect.Value, 1, 5)
1000 structs[0] = val
1001
1002 // Compile the list of all the fields that we're going to be decoding
1003 // from all the structs.
1004 type field struct {
1005 field reflect.StructField
1006 val reflect.Value
1007 }
1008 fields := []field{}
1009 for len(structs) > 0 {
1010 structVal := structs[0]
1011 structs = structs[1:]
1012
1013 structType := structVal.Type()
1014
1015 for i := 0; i < structType.NumField(); i++ {
1016 fieldType := structType.Field(i)
1017 fieldKind := fieldType.Type.Kind()
1018
1019 // If "squash" is specified in the tag, we squash the field down.
1020 squash := false
1021 tagParts := strings.Split(fieldType.Tag.Get(d.config.TagName), ",")
1022 for _, tag := range tagParts[1:] {
1023 if tag == "squash" {
1024 squash = true
1025 break
1026 }
1027 }
1028
1029 if squash {
1030 if fieldKind != reflect.Struct {
1031 errors = appendErrors(errors,
1032 fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldKind))
1033 } else {
1034 structs = append(structs, structVal.FieldByName(fieldType.Name))
1035 }
1036 continue
1037 }
1038
1039 // Normal struct field, store it away
1040 fields = append(fields, field{fieldType, structVal.Field(i)})
1041 }
1042 }
1043
1044 // for fieldType, field := range fields {
1045 for _, f := range fields {
1046 field, fieldValue := f.field, f.val
1047 fieldName := field.Name
1048
1049 tagValue := field.Tag.Get(d.config.TagName)
1050 tagValue = strings.SplitN(tagValue, ",", 2)[0]
1051 if tagValue != "" {
1052 fieldName = tagValue
1053 }
1054
1055 rawMapKey := reflect.ValueOf(fieldName)
1056 rawMapVal := dataVal.MapIndex(rawMapKey)
1057 if !rawMapVal.IsValid() {
1058 // Do a slower search by iterating over each key and
1059 // doing case-insensitive search.
1060 for dataValKey := range dataValKeys {
1061 mK, ok := dataValKey.Interface().(string)
1062 if !ok {
1063 // Not a string key
1064 continue
1065 }
1066
1067 if strings.EqualFold(mK, fieldName) {
1068 rawMapKey = dataValKey
1069 rawMapVal = dataVal.MapIndex(dataValKey)
1070 break
1071 }
1072 }
1073
1074 if !rawMapVal.IsValid() {
1075 // There was no matching key in the map for the value in
1076 // the struct. Just ignore.
1077 continue
1078 }
1079 }
1080
1081 // Delete the key we're using from the unused map so we stop tracking
1082 delete(dataValKeysUnused, rawMapKey.Interface())
1083
1084 if !fieldValue.IsValid() {
1085 // This should never happen
1086 panic("field is not valid")
1087 }
1088
1089 // If we can't set the field, then it is unexported or something,
1090 // and we just continue onwards.
1091 if !fieldValue.CanSet() {
1092 continue
1093 }
1094
1095 // If the name is empty string, then we're at the root, and we
1096 // don't dot-join the fields.
1097 if name != "" {
1098 fieldName = fmt.Sprintf("%s.%s", name, fieldName)
1099 }
1100
1101 if err := d.decode(fieldName, rawMapVal.Interface(), fieldValue); err != nil {
1102 errors = appendErrors(errors, err)
1103 }
1104 }
1105
1106 if d.config.ErrorUnused && len(dataValKeysUnused) > 0 {
1107 keys := make([]string, 0, len(dataValKeysUnused))
1108 for rawKey := range dataValKeysUnused {
1109 keys = append(keys, rawKey.(string))
1110 }
1111 sort.Strings(keys)
1112
1113 err := fmt.Errorf("'%s' has invalid keys: %s", name, strings.Join(keys, ", "))
1114 errors = appendErrors(errors, err)
1115 }
1116
1117 if len(errors) > 0 {
1118 return &Error{errors}
1119 }
1120
1121 // Add the unused keys to the list of unused keys if we're tracking metadata
1122 if d.config.Metadata != nil {
1123 for rawKey := range dataValKeysUnused {
1124 key := rawKey.(string)
1125 if name != "" {
1126 key = fmt.Sprintf("%s.%s", name, key)
1127 }
1128
1129 d.config.Metadata.Unused = append(d.config.Metadata.Unused, key)
1130 }
1131 }
1132
1133 return nil
1134}
1135
1136func getKind(val reflect.Value) reflect.Kind {
1137 kind := val.Kind()
1138
1139 switch {
1140 case kind >= reflect.Int && kind <= reflect.Int64:
1141 return reflect.Int
1142 case kind >= reflect.Uint && kind <= reflect.Uint64:
1143 return reflect.Uint
1144 case kind >= reflect.Float32 && kind <= reflect.Float64:
1145 return reflect.Float32
1146 default:
1147 return kind
1148 }
1149}