Tizen_4.0 base
[platform/upstream/docker-engine.git] / vendor / github.com / mitchellh / mapstructure / mapstructure.go
1 // The mapstructure package exposes functionality to convert an
2 // abitrary 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.
8 package mapstructure
9
10 import (
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.
33 type DecodeHookFunc interface{}
34
35 type DecodeHookFuncType func(reflect.Type, reflect.Type, interface{}) (interface{}, error)
36 type DecodeHookFuncKind func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error)
37
38 // DecoderConfig is the configuration that is used to create a new decoder
39 // and allows customization of various aspects of decoding.
40 type DecoderConfig struct {
41         // DecodeHook, if set, will be called before any decoding and any
42         // type conversion (if WeaklyTypedInput is on). This lets you modify
43         // the values before they're set down onto the resulting struct.
44         //
45         // If an error is returned, the entire decode will fail with that
46         // error.
47         DecodeHook DecodeHookFunc
48
49         // If ErrorUnused is true, then it is an error for there to exist
50         // keys in the original map that were unused in the decoding process
51         // (extra keys).
52         ErrorUnused bool
53
54         // ZeroFields, if set to true, will zero fields before writing them.
55         // For example, a map will be emptied before decoded values are put in
56         // it. If this is false, a map will be merged.
57         ZeroFields bool
58
59         // If WeaklyTypedInput is true, the decoder will make the following
60         // "weak" conversions:
61         //
62         //   - bools to string (true = "1", false = "0")
63         //   - numbers to string (base 10)
64         //   - bools to int/uint (true = 1, false = 0)
65         //   - strings to int/uint (base implied by prefix)
66         //   - int to bool (true if value != 0)
67         //   - string to bool (accepts: 1, t, T, TRUE, true, True, 0, f, F,
68         //     FALSE, false, False. Anything else is an error)
69         //   - empty array = empty map and vice versa
70         //   - negative numbers to overflowed uint values (base 10)
71         //   - slice of maps to a merged map
72         //
73         WeaklyTypedInput bool
74
75         // Metadata is the struct that will contain extra metadata about
76         // the decoding. If this is nil, then no metadata will be tracked.
77         Metadata *Metadata
78
79         // Result is a pointer to the struct that will contain the decoded
80         // value.
81         Result interface{}
82
83         // The tag name that mapstructure reads for field names. This
84         // defaults to "mapstructure"
85         TagName string
86 }
87
88 // A Decoder takes a raw interface value and turns it into structured
89 // data, keeping track of rich error information along the way in case
90 // anything goes wrong. Unlike the basic top-level Decode method, you can
91 // more finely control how the Decoder behaves using the DecoderConfig
92 // structure. The top-level Decode method is just a convenience that sets
93 // up the most basic Decoder.
94 type Decoder struct {
95         config *DecoderConfig
96 }
97
98 // Metadata contains information about decoding a structure that
99 // is tedious or difficult to get otherwise.
100 type Metadata struct {
101         // Keys are the keys of the structure which were successfully decoded
102         Keys []string
103
104         // Unused is a slice of keys that were found in the raw value but
105         // weren't decoded since there was no matching field in the result interface
106         Unused []string
107 }
108
109 // Decode takes a map and uses reflection to convert it into the
110 // given Go native structure. val must be a pointer to a struct.
111 func Decode(m interface{}, rawVal interface{}) error {
112         config := &DecoderConfig{
113                 Metadata: nil,
114                 Result:   rawVal,
115         }
116
117         decoder, err := NewDecoder(config)
118         if err != nil {
119                 return err
120         }
121
122         return decoder.Decode(m)
123 }
124
125 // WeakDecode is the same as Decode but is shorthand to enable
126 // WeaklyTypedInput. See DecoderConfig for more info.
127 func WeakDecode(input, output interface{}) error {
128         config := &DecoderConfig{
129                 Metadata:         nil,
130                 Result:           output,
131                 WeaklyTypedInput: true,
132         }
133
134         decoder, err := NewDecoder(config)
135         if err != nil {
136                 return err
137         }
138
139         return decoder.Decode(input)
140 }
141
142 // NewDecoder returns a new decoder for the given configuration. Once
143 // a decoder has been returned, the same configuration must not be used
144 // again.
145 func NewDecoder(config *DecoderConfig) (*Decoder, error) {
146         val := reflect.ValueOf(config.Result)
147         if val.Kind() != reflect.Ptr {
148                 return nil, errors.New("result must be a pointer")
149         }
150
151         val = val.Elem()
152         if !val.CanAddr() {
153                 return nil, errors.New("result must be addressable (a pointer)")
154         }
155
156         if config.Metadata != nil {
157                 if config.Metadata.Keys == nil {
158                         config.Metadata.Keys = make([]string, 0)
159                 }
160
161                 if config.Metadata.Unused == nil {
162                         config.Metadata.Unused = make([]string, 0)
163                 }
164         }
165
166         if config.TagName == "" {
167                 config.TagName = "mapstructure"
168         }
169
170         result := &Decoder{
171                 config: config,
172         }
173
174         return result, nil
175 }
176
177 // Decode decodes the given raw interface to the target pointer specified
178 // by the configuration.
179 func (d *Decoder) Decode(raw interface{}) error {
180         return d.decode("", raw, reflect.ValueOf(d.config.Result).Elem())
181 }
182
183 // Decodes an unknown data type into a specific reflection value.
184 func (d *Decoder) decode(name string, data interface{}, val reflect.Value) error {
185         if data == nil {
186                 // If the data is nil, then we don't set anything.
187                 return nil
188         }
189
190         dataVal := reflect.ValueOf(data)
191         if !dataVal.IsValid() {
192                 // If the data value is invalid, then we just set the value
193                 // to be the zero value.
194                 val.Set(reflect.Zero(val.Type()))
195                 return nil
196         }
197
198         if d.config.DecodeHook != nil {
199                 // We have a DecodeHook, so let's pre-process the data.
200                 var err error
201                 data, err = DecodeHookExec(
202                         d.config.DecodeHook,
203                         dataVal.Type(), val.Type(), data)
204                 if err != nil {
205                         return err
206                 }
207         }
208
209         var err error
210         dataKind := getKind(val)
211         switch dataKind {
212         case reflect.Bool:
213                 err = d.decodeBool(name, data, val)
214         case reflect.Interface:
215                 err = d.decodeBasic(name, data, val)
216         case reflect.String:
217                 err = d.decodeString(name, data, val)
218         case reflect.Int:
219                 err = d.decodeInt(name, data, val)
220         case reflect.Uint:
221                 err = d.decodeUint(name, data, val)
222         case reflect.Float32:
223                 err = d.decodeFloat(name, data, val)
224         case reflect.Struct:
225                 err = d.decodeStruct(name, data, val)
226         case reflect.Map:
227                 err = d.decodeMap(name, data, val)
228         case reflect.Ptr:
229                 err = d.decodePtr(name, data, val)
230         case reflect.Slice:
231                 err = d.decodeSlice(name, data, val)
232         default:
233                 // If we reached this point then we weren't able to decode it
234                 return fmt.Errorf("%s: unsupported type: %s", name, dataKind)
235         }
236
237         // If we reached here, then we successfully decoded SOMETHING, so
238         // mark the key as used if we're tracking metadata.
239         if d.config.Metadata != nil && name != "" {
240                 d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
241         }
242
243         return err
244 }
245
246 // This decodes a basic type (bool, int, string, etc.) and sets the
247 // value to "data" of that type.
248 func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error {
249         dataVal := reflect.ValueOf(data)
250         if !dataVal.IsValid() {
251                 dataVal = reflect.Zero(val.Type())
252         }
253
254         dataValType := dataVal.Type()
255         if !dataValType.AssignableTo(val.Type()) {
256                 return fmt.Errorf(
257                         "'%s' expected type '%s', got '%s'",
258                         name, val.Type(), dataValType)
259         }
260
261         val.Set(dataVal)
262         return nil
263 }
264
265 func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) error {
266         dataVal := reflect.ValueOf(data)
267         dataKind := getKind(dataVal)
268
269         converted := true
270         switch {
271         case dataKind == reflect.String:
272                 val.SetString(dataVal.String())
273         case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
274                 if dataVal.Bool() {
275                         val.SetString("1")
276                 } else {
277                         val.SetString("0")
278                 }
279         case dataKind == reflect.Int && d.config.WeaklyTypedInput:
280                 val.SetString(strconv.FormatInt(dataVal.Int(), 10))
281         case dataKind == reflect.Uint && d.config.WeaklyTypedInput:
282                 val.SetString(strconv.FormatUint(dataVal.Uint(), 10))
283         case dataKind == reflect.Float32 && d.config.WeaklyTypedInput:
284                 val.SetString(strconv.FormatFloat(dataVal.Float(), 'f', -1, 64))
285         case dataKind == reflect.Slice && d.config.WeaklyTypedInput:
286                 dataType := dataVal.Type()
287                 elemKind := dataType.Elem().Kind()
288                 switch {
289                 case elemKind == reflect.Uint8:
290                         val.SetString(string(dataVal.Interface().([]uint8)))
291                 default:
292                         converted = false
293                 }
294         default:
295                 converted = false
296         }
297
298         if !converted {
299                 return fmt.Errorf(
300                         "'%s' expected type '%s', got unconvertible type '%s'",
301                         name, val.Type(), dataVal.Type())
302         }
303
304         return nil
305 }
306
307 func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) error {
308         dataVal := reflect.ValueOf(data)
309         dataKind := getKind(dataVal)
310         dataType := dataVal.Type()
311
312         switch {
313         case dataKind == reflect.Int:
314                 val.SetInt(dataVal.Int())
315         case dataKind == reflect.Uint:
316                 val.SetInt(int64(dataVal.Uint()))
317         case dataKind == reflect.Float32:
318                 val.SetInt(int64(dataVal.Float()))
319         case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
320                 if dataVal.Bool() {
321                         val.SetInt(1)
322                 } else {
323                         val.SetInt(0)
324                 }
325         case dataKind == reflect.String && d.config.WeaklyTypedInput:
326                 i, err := strconv.ParseInt(dataVal.String(), 0, val.Type().Bits())
327                 if err == nil {
328                         val.SetInt(i)
329                 } else {
330                         return fmt.Errorf("cannot parse '%s' as int: %s", name, err)
331                 }
332         case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
333                 jn := data.(json.Number)
334                 i, err := jn.Int64()
335                 if err != nil {
336                         return fmt.Errorf(
337                                 "error decoding json.Number into %s: %s", name, err)
338                 }
339                 val.SetInt(i)
340         default:
341                 return fmt.Errorf(
342                         "'%s' expected type '%s', got unconvertible type '%s'",
343                         name, val.Type(), dataVal.Type())
344         }
345
346         return nil
347 }
348
349 func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) error {
350         dataVal := reflect.ValueOf(data)
351         dataKind := getKind(dataVal)
352
353         switch {
354         case dataKind == reflect.Int:
355                 i := dataVal.Int()
356                 if i < 0 && !d.config.WeaklyTypedInput {
357                         return fmt.Errorf("cannot parse '%s', %d overflows uint",
358                                 name, i)
359                 }
360                 val.SetUint(uint64(i))
361         case dataKind == reflect.Uint:
362                 val.SetUint(dataVal.Uint())
363         case dataKind == reflect.Float32:
364                 f := dataVal.Float()
365                 if f < 0 && !d.config.WeaklyTypedInput {
366                         return fmt.Errorf("cannot parse '%s', %f overflows uint",
367                                 name, f)
368                 }
369                 val.SetUint(uint64(f))
370         case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
371                 if dataVal.Bool() {
372                         val.SetUint(1)
373                 } else {
374                         val.SetUint(0)
375                 }
376         case dataKind == reflect.String && d.config.WeaklyTypedInput:
377                 i, err := strconv.ParseUint(dataVal.String(), 0, val.Type().Bits())
378                 if err == nil {
379                         val.SetUint(i)
380                 } else {
381                         return fmt.Errorf("cannot parse '%s' as uint: %s", name, err)
382                 }
383         default:
384                 return fmt.Errorf(
385                         "'%s' expected type '%s', got unconvertible type '%s'",
386                         name, val.Type(), dataVal.Type())
387         }
388
389         return nil
390 }
391
392 func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) error {
393         dataVal := reflect.ValueOf(data)
394         dataKind := getKind(dataVal)
395
396         switch {
397         case dataKind == reflect.Bool:
398                 val.SetBool(dataVal.Bool())
399         case dataKind == reflect.Int && d.config.WeaklyTypedInput:
400                 val.SetBool(dataVal.Int() != 0)
401         case dataKind == reflect.Uint && d.config.WeaklyTypedInput:
402                 val.SetBool(dataVal.Uint() != 0)
403         case dataKind == reflect.Float32 && d.config.WeaklyTypedInput:
404                 val.SetBool(dataVal.Float() != 0)
405         case dataKind == reflect.String && d.config.WeaklyTypedInput:
406                 b, err := strconv.ParseBool(dataVal.String())
407                 if err == nil {
408                         val.SetBool(b)
409                 } else if dataVal.String() == "" {
410                         val.SetBool(false)
411                 } else {
412                         return fmt.Errorf("cannot parse '%s' as bool: %s", name, err)
413                 }
414         default:
415                 return fmt.Errorf(
416                         "'%s' expected type '%s', got unconvertible type '%s'",
417                         name, val.Type(), dataVal.Type())
418         }
419
420         return nil
421 }
422
423 func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) error {
424         dataVal := reflect.ValueOf(data)
425         dataKind := getKind(dataVal)
426         dataType := dataVal.Type()
427
428         switch {
429         case dataKind == reflect.Int:
430                 val.SetFloat(float64(dataVal.Int()))
431         case dataKind == reflect.Uint:
432                 val.SetFloat(float64(dataVal.Uint()))
433         case dataKind == reflect.Float32:
434                 val.SetFloat(float64(dataVal.Float()))
435         case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
436                 if dataVal.Bool() {
437                         val.SetFloat(1)
438                 } else {
439                         val.SetFloat(0)
440                 }
441         case dataKind == reflect.String && d.config.WeaklyTypedInput:
442                 f, err := strconv.ParseFloat(dataVal.String(), val.Type().Bits())
443                 if err == nil {
444                         val.SetFloat(f)
445                 } else {
446                         return fmt.Errorf("cannot parse '%s' as float: %s", name, err)
447                 }
448         case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
449                 jn := data.(json.Number)
450                 i, err := jn.Float64()
451                 if err != nil {
452                         return fmt.Errorf(
453                                 "error decoding json.Number into %s: %s", name, err)
454                 }
455                 val.SetFloat(i)
456         default:
457                 return fmt.Errorf(
458                         "'%s' expected type '%s', got unconvertible type '%s'",
459                         name, val.Type(), dataVal.Type())
460         }
461
462         return nil
463 }
464
465 func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) error {
466         valType := val.Type()
467         valKeyType := valType.Key()
468         valElemType := valType.Elem()
469
470         // By default we overwrite keys in the current map
471         valMap := val
472
473         // If the map is nil or we're purposely zeroing fields, make a new map
474         if valMap.IsNil() || d.config.ZeroFields {
475                 // Make a new map to hold our result
476                 mapType := reflect.MapOf(valKeyType, valElemType)
477                 valMap = reflect.MakeMap(mapType)
478         }
479
480         // Check input type
481         dataVal := reflect.Indirect(reflect.ValueOf(data))
482         if dataVal.Kind() != reflect.Map {
483                 // In weak mode, we accept a slice of maps as an input...
484                 if d.config.WeaklyTypedInput {
485                         switch dataVal.Kind() {
486                         case reflect.Array, reflect.Slice:
487                                 // Special case for BC reasons (covered by tests)
488                                 if dataVal.Len() == 0 {
489                                         val.Set(valMap)
490                                         return nil
491                                 }
492
493                                 for i := 0; i < dataVal.Len(); i++ {
494                                         err := d.decode(
495                                                 fmt.Sprintf("%s[%d]", name, i),
496                                                 dataVal.Index(i).Interface(), val)
497                                         if err != nil {
498                                                 return err
499                                         }
500                                 }
501
502                                 return nil
503                         }
504                 }
505
506                 return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind())
507         }
508
509         // Accumulate errors
510         errors := make([]string, 0)
511
512         for _, k := range dataVal.MapKeys() {
513                 fieldName := fmt.Sprintf("%s[%s]", name, k)
514
515                 // First decode the key into the proper type
516                 currentKey := reflect.Indirect(reflect.New(valKeyType))
517                 if err := d.decode(fieldName, k.Interface(), currentKey); err != nil {
518                         errors = appendErrors(errors, err)
519                         continue
520                 }
521
522                 // Next decode the data into the proper type
523                 v := dataVal.MapIndex(k).Interface()
524                 currentVal := reflect.Indirect(reflect.New(valElemType))
525                 if err := d.decode(fieldName, v, currentVal); err != nil {
526                         errors = appendErrors(errors, err)
527                         continue
528                 }
529
530                 valMap.SetMapIndex(currentKey, currentVal)
531         }
532
533         // Set the built up map to the value
534         val.Set(valMap)
535
536         // If we had errors, return those
537         if len(errors) > 0 {
538                 return &Error{errors}
539         }
540
541         return nil
542 }
543
544 func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) error {
545         // Create an element of the concrete (non pointer) type and decode
546         // into that. Then set the value of the pointer to this type.
547         valType := val.Type()
548         valElemType := valType.Elem()
549         realVal := reflect.New(valElemType)
550         if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil {
551                 return err
552         }
553
554         val.Set(realVal)
555         return nil
556 }
557
558 func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error {
559         dataVal := reflect.Indirect(reflect.ValueOf(data))
560         dataValKind := dataVal.Kind()
561         valType := val.Type()
562         valElemType := valType.Elem()
563         sliceType := reflect.SliceOf(valElemType)
564
565         // Check input type
566         if dataValKind != reflect.Array && dataValKind != reflect.Slice {
567                 // Accept empty map instead of array/slice in weakly typed mode
568                 if d.config.WeaklyTypedInput && dataVal.Kind() == reflect.Map && dataVal.Len() == 0 {
569                         val.Set(reflect.MakeSlice(sliceType, 0, 0))
570                         return nil
571                 } else {
572                         return fmt.Errorf(
573                                 "'%s': source data must be an array or slice, got %s", name, dataValKind)
574                 }
575         }
576
577         // Make a new slice to hold our result, same size as the original data.
578         valSlice := reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len())
579
580         // Accumulate any errors
581         errors := make([]string, 0)
582
583         for i := 0; i < dataVal.Len(); i++ {
584                 currentData := dataVal.Index(i).Interface()
585                 currentField := valSlice.Index(i)
586
587                 fieldName := fmt.Sprintf("%s[%d]", name, i)
588                 if err := d.decode(fieldName, currentData, currentField); err != nil {
589                         errors = appendErrors(errors, err)
590                 }
591         }
592
593         // Finally, set the value to the slice we built up
594         val.Set(valSlice)
595
596         // If there were errors, we return those
597         if len(errors) > 0 {
598                 return &Error{errors}
599         }
600
601         return nil
602 }
603
604 func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) error {
605         dataVal := reflect.Indirect(reflect.ValueOf(data))
606
607         // If the type of the value to write to and the data match directly,
608         // then we just set it directly instead of recursing into the structure.
609         if dataVal.Type() == val.Type() {
610                 val.Set(dataVal)
611                 return nil
612         }
613
614         dataValKind := dataVal.Kind()
615         if dataValKind != reflect.Map {
616                 return fmt.Errorf("'%s' expected a map, got '%s'", name, dataValKind)
617         }
618
619         dataValType := dataVal.Type()
620         if kind := dataValType.Key().Kind(); kind != reflect.String && kind != reflect.Interface {
621                 return fmt.Errorf(
622                         "'%s' needs a map with string keys, has '%s' keys",
623                         name, dataValType.Key().Kind())
624         }
625
626         dataValKeys := make(map[reflect.Value]struct{})
627         dataValKeysUnused := make(map[interface{}]struct{})
628         for _, dataValKey := range dataVal.MapKeys() {
629                 dataValKeys[dataValKey] = struct{}{}
630                 dataValKeysUnused[dataValKey.Interface()] = struct{}{}
631         }
632
633         errors := make([]string, 0)
634
635         // This slice will keep track of all the structs we'll be decoding.
636         // There can be more than one struct if there are embedded structs
637         // that are squashed.
638         structs := make([]reflect.Value, 1, 5)
639         structs[0] = val
640
641         // Compile the list of all the fields that we're going to be decoding
642         // from all the structs.
643         fields := make(map[*reflect.StructField]reflect.Value)
644         for len(structs) > 0 {
645                 structVal := structs[0]
646                 structs = structs[1:]
647
648                 structType := structVal.Type()
649
650                 for i := 0; i < structType.NumField(); i++ {
651                         fieldType := structType.Field(i)
652                         fieldKind := fieldType.Type.Kind()
653
654                         // If "squash" is specified in the tag, we squash the field down.
655                         squash := false
656                         tagParts := strings.Split(fieldType.Tag.Get(d.config.TagName), ",")
657                         for _, tag := range tagParts[1:] {
658                                 if tag == "squash" {
659                                         squash = true
660                                         break
661                                 }
662                         }
663
664                         if squash {
665                                 if fieldKind != reflect.Struct {
666                                         errors = appendErrors(errors,
667                                                 fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldKind))
668                                 } else {
669                                         structs = append(structs, val.FieldByName(fieldType.Name))
670                                 }
671                                 continue
672                         }
673
674                         // Normal struct field, store it away
675                         fields[&fieldType] = structVal.Field(i)
676                 }
677         }
678
679         for fieldType, field := range fields {
680                 fieldName := fieldType.Name
681
682                 tagValue := fieldType.Tag.Get(d.config.TagName)
683                 tagValue = strings.SplitN(tagValue, ",", 2)[0]
684                 if tagValue != "" {
685                         fieldName = tagValue
686                 }
687
688                 rawMapKey := reflect.ValueOf(fieldName)
689                 rawMapVal := dataVal.MapIndex(rawMapKey)
690                 if !rawMapVal.IsValid() {
691                         // Do a slower search by iterating over each key and
692                         // doing case-insensitive search.
693                         for dataValKey := range dataValKeys {
694                                 mK, ok := dataValKey.Interface().(string)
695                                 if !ok {
696                                         // Not a string key
697                                         continue
698                                 }
699
700                                 if strings.EqualFold(mK, fieldName) {
701                                         rawMapKey = dataValKey
702                                         rawMapVal = dataVal.MapIndex(dataValKey)
703                                         break
704                                 }
705                         }
706
707                         if !rawMapVal.IsValid() {
708                                 // There was no matching key in the map for the value in
709                                 // the struct. Just ignore.
710                                 continue
711                         }
712                 }
713
714                 // Delete the key we're using from the unused map so we stop tracking
715                 delete(dataValKeysUnused, rawMapKey.Interface())
716
717                 if !field.IsValid() {
718                         // This should never happen
719                         panic("field is not valid")
720                 }
721
722                 // If we can't set the field, then it is unexported or something,
723                 // and we just continue onwards.
724                 if !field.CanSet() {
725                         continue
726                 }
727
728                 // If the name is empty string, then we're at the root, and we
729                 // don't dot-join the fields.
730                 if name != "" {
731                         fieldName = fmt.Sprintf("%s.%s", name, fieldName)
732                 }
733
734                 if err := d.decode(fieldName, rawMapVal.Interface(), field); err != nil {
735                         errors = appendErrors(errors, err)
736                 }
737         }
738
739         if d.config.ErrorUnused && len(dataValKeysUnused) > 0 {
740                 keys := make([]string, 0, len(dataValKeysUnused))
741                 for rawKey := range dataValKeysUnused {
742                         keys = append(keys, rawKey.(string))
743                 }
744                 sort.Strings(keys)
745
746                 err := fmt.Errorf("'%s' has invalid keys: %s", name, strings.Join(keys, ", "))
747                 errors = appendErrors(errors, err)
748         }
749
750         if len(errors) > 0 {
751                 return &Error{errors}
752         }
753
754         // Add the unused keys to the list of unused keys if we're tracking metadata
755         if d.config.Metadata != nil {
756                 for rawKey := range dataValKeysUnused {
757                         key := rawKey.(string)
758                         if name != "" {
759                                 key = fmt.Sprintf("%s.%s", name, key)
760                         }
761
762                         d.config.Metadata.Unused = append(d.config.Metadata.Unused, key)
763                 }
764         }
765
766         return nil
767 }
768
769 func getKind(val reflect.Value) reflect.Kind {
770         kind := val.Kind()
771
772         switch {
773         case kind >= reflect.Int && kind <= reflect.Int64:
774                 return reflect.Int
775         case kind >= reflect.Uint && kind <= reflect.Uint64:
776                 return reflect.Uint
777         case kind >= reflect.Float32 && kind <= reflect.Float64:
778                 return reflect.Float32
779         default:
780                 return kind
781         }
782 }