OSDN Git Service

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