1 // Package mapstructure exposes functionality to convert one arbitrary
2 // Go type into another, typically to convert a map[string]interface{}
3 // into a native Go structure.
4 //
5 // The Go structure can be arbitrarily complex, containing slices,
6 // other structs, etc. and the decoder will properly decode nested
7 // maps and so on into the proper structures in the native Go struct.
8 // See the examples to see what the decoder is capable of.
9 //
10 // The simplest function to start with is Decode.
11 //
12 // Field Tags
13 //
14 // When decoding to a struct, mapstructure will use the field name by
15 // default to perform the mapping. For example, if a struct has a field
16 // "Username" then mapstructure will look for a key in the source value
17 // of "username" (case insensitive).
18 //
19 // type User struct {
20 // Username string
21 // }
22 //
23 // You can change the behavior of mapstructure by using struct tags.
24 // The default struct tag that mapstructure looks for is "mapstructure"
25 // but you can customize it using DecoderConfig.
26 //
27 // Renaming Fields
28 //
29 // To rename the key that mapstructure looks for, use the "mapstructure"
30 // tag and set a value directly. For example, to change the "username" example
31 // above to "user":
32 //
33 // type User struct {
34 // Username string `mapstructure:"user"`
35 // }
36 //
37 // Embedded Structs and Squashing
38 //
39 // Embedded structs are treated as if they're another field with that name.
40 // By default, the two structs below are equivalent when decoding with
41 // mapstructure:
42 //
43 // type Person struct {
44 // Name string
45 // }
46 //
47 // type Friend struct {
48 // Person
49 // }
50 //
51 // type Friend struct {
52 // Person Person
53 // }
54 //
55 // This would require an input that looks like below:
56 //
57 // map[string]interface{}{
58 // "person": map[string]interface{}{"name": "alice"},
59 // }
60 //
61 // If your "person" value is NOT nested, then you can append ",squash" to
62 // your tag value and mapstructure will treat it as if the embedded struct
63 // were part of the struct directly. Example:
64 //
65 // type Friend struct {
66 // Person `mapstructure:",squash"`
67 // }
68 //
69 // Now the following input would be accepted:
70 //
71 // map[string]interface{}{
72 // "name": "alice",
73 // }
74 //
75 // When decoding from a struct to a map, the squash tag squashes the struct
76 // fields into a single map. Using the example structs from above:
77 //
78 // Friend{Person: Person{Name: "alice"}}
79 //
80 // Will be decoded into a map:
81 //
82 // map[string]interface{}{
83 // "name": "alice",
84 // }
85 //
86 // DecoderConfig has a field that changes the behavior of mapstructure
87 // to always squash embedded structs.
88 //
89 // Remainder Values
90 //
91 // If there are any unmapped keys in the source value, mapstructure by
92 // default will silently ignore them. You can error by setting ErrorUnused
93 // in DecoderConfig. If you're using Metadata you can also maintain a slice
94 // of the unused keys.
95 //
96 // You can also use the ",remain" suffix on your tag to collect all unused
97 // values in a map. The field with this tag MUST be a map type and should
98 // probably be a "map[string]interface{}" or "map[interface{}]interface{}".
99 // See example below:
100 //
101 // type Friend struct {
102 // Name string
103 // Other map[string]interface{} `mapstructure:",remain"`
104 // }
105 //
106 // Given the input below, Other would be populated with the other
107 // values that weren't used (everything but "name"):
108 //
109 // map[string]interface{}{
110 // "name": "bob",
111 // "address": "123 Maple St.",
112 // }
113 //
114 // Omit Empty Values
115 //
116 // When decoding from a struct to any other value, you may use the
117 // ",omitempty" suffix on your tag to omit that value if it equates to
118 // the zero value. The zero value of all types is specified in the Go
119 // specification.
120 //
121 // For example, the zero type of a numeric type is zero ("0"). If the struct
122 // field value is zero and a numeric type, the field is empty, and it won't
123 // be encoded into the destination type.
124 //
125 // type Source struct {
126 // Age int `mapstructure:",omitempty"`
127 // }
128 //
129 // Unexported fields
130 //
131 // Since unexported (private) struct fields cannot be set outside the package
132 // where they are defined, the decoder will simply skip them.
133 //
134 // For this output type definition:
135 //
136 // type Exported struct {
137 // private string // this unexported field will be skipped
138 // Public string
139 // }
140 //
141 // Using this map as input:
142 //
143 // map[string]interface{}{
144 // "private": "I will be ignored",
145 // "Public": "I made it through!",
146 // }
147 //
148 // The following struct will be decoded:
149 //
150 // type Exported struct {
151 // private: "" // field is left with an empty string (zero value)
152 // Public: "I made it through!"
153 // }
154 //
155 // Other Configuration
156 //
157 // mapstructure is highly configurable. See the DecoderConfig struct
158 // for other features and options that are supported.
159 package mapstructure
160 161 import (
162 "encoding/json"
163 "errors"
164 "fmt"
165 "reflect"
166 "sort"
167 "strconv"
168 "strings"
169 )
170 171 // DecodeHookFunc is the callback function that can be used for
172 // data transformations. See "DecodeHook" in the DecoderConfig
173 // struct.
174 //
175 // The type must be one of DecodeHookFuncType, DecodeHookFuncKind, or
176 // DecodeHookFuncValue.
177 // Values are a superset of Types (Values can return types), and Types are a
178 // superset of Kinds (Types can return Kinds) and are generally a richer thing
179 // to use, but Kinds are simpler if you only need those.
180 //
181 // The reason DecodeHookFunc is multi-typed is for backwards compatibility:
182 // we started with Kinds and then realized Types were the better solution,
183 // but have a promise to not break backwards compat so we now support
184 // both.
185 type DecodeHookFunc interface{}
186 187 // DecodeHookFuncType is a DecodeHookFunc which has complete information about
188 // the source and target types.
189 type DecodeHookFuncType func(reflect.Type, reflect.Type, interface{}) (interface{}, error)
190 191 // DecodeHookFuncKind is a DecodeHookFunc which knows only the Kinds of the
192 // source and target types.
193 type DecodeHookFuncKind func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error)
194 195 // DecodeHookFuncValue is a DecodeHookFunc which has complete access to both the source and target
196 // values.
197 type DecodeHookFuncValue func(from reflect.Value, to reflect.Value) (interface{}, error)
198 199 // DecoderConfig is the configuration that is used to create a new decoder
200 // and allows customization of various aspects of decoding.
201 type DecoderConfig struct {
202 // DecodeHook, if set, will be called before any decoding and any
203 // type conversion (if WeaklyTypedInput is on). This lets you modify
204 // the values before they're set down onto the resulting struct. The
205 // DecodeHook is called for every map and value in the input. This means
206 // that if a struct has embedded fields with squash tags the decode hook
207 // is called only once with all of the input data, not once for each
208 // embedded struct.
209 //
210 // If an error is returned, the entire decode will fail with that error.
211 DecodeHook DecodeHookFunc
212 213 // If ErrorUnused is true, then it is an error for there to exist
214 // keys in the original map that were unused in the decoding process
215 // (extra keys).
216 ErrorUnused bool
217 218 // If ErrorUnset is true, then it is an error for there to exist
219 // fields in the result that were not set in the decoding process
220 // (extra fields). This only applies to decoding to a struct. This
221 // will affect all nested structs as well.
222 ErrorUnset bool
223 224 // ZeroFields, if set to true, will zero fields before writing them.
225 // For example, a map will be emptied before decoded values are put in
226 // it. If this is false, a map will be merged.
227 ZeroFields bool
228 229 // If WeaklyTypedInput is true, the decoder will make the following
230 // "weak" conversions:
231 //
232 // - bools to string (true = "1", false = "0")
233 // - numbers to string (base 10)
234 // - bools to int/uint (true = 1, false = 0)
235 // - strings to int/uint (base implied by prefix)
236 // - int to bool (true if value != 0)
237 // - string to bool (accepts: 1, t, T, TRUE, true, True, 0, f, F,
238 // FALSE, false, False. Anything else is an error)
239 // - empty array = empty map and vice versa
240 // - negative numbers to overflowed uint values (base 10)
241 // - slice of maps to a merged map
242 // - single values are converted to slices if required. Each
243 // element is weakly decoded. For example: "4" can become []int{4}
244 // if the target type is an int slice.
245 //
246 WeaklyTypedInput bool
247 248 // Squash will squash embedded structs. A squash tag may also be
249 // added to an individual struct field using a tag. For example:
250 //
251 // type Parent struct {
252 // Child `mapstructure:",squash"`
253 // }
254 Squash bool
255 256 // Metadata is the struct that will contain extra metadata about
257 // the decoding. If this is nil, then no metadata will be tracked.
258 Metadata *Metadata
259 260 // Result is a pointer to the struct that will contain the decoded
261 // value.
262 Result interface{}
263 264 // The tag name that mapstructure reads for field names. This
265 // defaults to "mapstructure"
266 TagName string
267 268 // IgnoreUntaggedFields ignores all struct fields without explicit
269 // TagName, comparable to `mapstructure:"-"` as default behaviour.
270 IgnoreUntaggedFields bool
271 272 // MatchName is the function used to match the map key to the struct
273 // field name or tag. Defaults to `strings.EqualFold`. This can be used
274 // to implement case-sensitive tag values, support snake casing, etc.
275 MatchName func(mapKey, fieldName string) bool
276 }
277 278 // A Decoder takes a raw interface value and turns it into structured
279 // data, keeping track of rich error information along the way in case
280 // anything goes wrong. Unlike the basic top-level Decode method, you can
281 // more finely control how the Decoder behaves using the DecoderConfig
282 // structure. The top-level Decode method is just a convenience that sets
283 // up the most basic Decoder.
284 type Decoder struct {
285 config *DecoderConfig
286 }
287 288 // Metadata contains information about decoding a structure that
289 // is tedious or difficult to get otherwise.
290 type Metadata struct {
291 // Keys are the keys of the structure which were successfully decoded
292 Keys []string
293 294 // Unused is a slice of keys that were found in the raw value but
295 // weren't decoded since there was no matching field in the result interface
296 Unused []string
297 298 // Unset is a slice of field names that were found in the result interface
299 // but weren't set in the decoding process since there was no matching value
300 // in the input
301 Unset []string
302 }
303 304 // Decode takes an input structure and uses reflection to translate it to
305 // the output structure. output must be a pointer to a map or struct.
306 func Decode(input interface{}, output interface{}) error {
307 config := &DecoderConfig{
308 Metadata: nil,
309 Result: output,
310 }
311 312 decoder, err := NewDecoder(config)
313 if err != nil {
314 return err
315 }
316 317 return decoder.Decode(input)
318 }
319 320 // WeakDecode is the same as Decode but is shorthand to enable
321 // WeaklyTypedInput. See DecoderConfig for more info.
322 func WeakDecode(input, output interface{}) error {
323 config := &DecoderConfig{
324 Metadata: nil,
325 Result: output,
326 WeaklyTypedInput: true,
327 }
328 329 decoder, err := NewDecoder(config)
330 if err != nil {
331 return err
332 }
333 334 return decoder.Decode(input)
335 }
336 337 // DecodeMetadata is the same as Decode, but is shorthand to
338 // enable metadata collection. See DecoderConfig for more info.
339 func DecodeMetadata(input interface{}, output interface{}, metadata *Metadata) error {
340 config := &DecoderConfig{
341 Metadata: metadata,
342 Result: output,
343 }
344 345 decoder, err := NewDecoder(config)
346 if err != nil {
347 return err
348 }
349 350 return decoder.Decode(input)
351 }
352 353 // WeakDecodeMetadata is the same as Decode, but is shorthand to
354 // enable both WeaklyTypedInput and metadata collection. See
355 // DecoderConfig for more info.
356 func WeakDecodeMetadata(input interface{}, output interface{}, metadata *Metadata) error {
357 config := &DecoderConfig{
358 Metadata: metadata,
359 Result: output,
360 WeaklyTypedInput: true,
361 }
362 363 decoder, err := NewDecoder(config)
364 if err != nil {
365 return err
366 }
367 368 return decoder.Decode(input)
369 }
370 371 // NewDecoder returns a new decoder for the given configuration. Once
372 // a decoder has been returned, the same configuration must not be used
373 // again.
374 func NewDecoder(config *DecoderConfig) (*Decoder, error) {
375 val := reflect.ValueOf(config.Result)
376 if val.Kind() != reflect.Ptr {
377 return nil, errors.New("result must be a pointer")
378 }
379 380 val = val.Elem()
381 if !val.CanAddr() {
382 return nil, errors.New("result must be addressable (a pointer)")
383 }
384 385 if config.Metadata != nil {
386 if config.Metadata.Keys == nil {
387 config.Metadata.Keys = make([]string, 0)
388 }
389 390 if config.Metadata.Unused == nil {
391 config.Metadata.Unused = make([]string, 0)
392 }
393 394 if config.Metadata.Unset == nil {
395 config.Metadata.Unset = make([]string, 0)
396 }
397 }
398 399 if config.TagName == "" {
400 config.TagName = "mapstructure"
401 }
402 403 if config.MatchName == nil {
404 config.MatchName = strings.EqualFold
405 }
406 407 result := &Decoder{
408 config: config,
409 }
410 411 return result, nil
412 }
413 414 // Decode decodes the given raw interface to the target pointer specified
415 // by the configuration.
416 func (d *Decoder) Decode(input interface{}) error {
417 return d.decode("", input, reflect.ValueOf(d.config.Result).Elem())
418 }
419 420 // Decodes an unknown data type into a specific reflection value.
421 func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) error {
422 var inputVal reflect.Value
423 if input != nil {
424 inputVal = reflect.ValueOf(input)
425 426 // We need to check here if input is a typed nil. Typed nils won't
427 // match the "input == nil" below so we check that here.
428 if inputVal.Kind() == reflect.Ptr && inputVal.IsNil() {
429 input = nil
430 }
431 }
432 433 if input == nil {
434 // If the data is nil, then we don't set anything, unless ZeroFields is set
435 // to true.
436 if d.config.ZeroFields {
437 outVal.Set(reflect.Zero(outVal.Type()))
438 439 if d.config.Metadata != nil && name != "" {
440 d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
441 }
442 }
443 return nil
444 }
445 446 if !inputVal.IsValid() {
447 // If the input value is invalid, then we just set the value
448 // to be the zero value.
449 outVal.Set(reflect.Zero(outVal.Type()))
450 if d.config.Metadata != nil && name != "" {
451 d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
452 }
453 return nil
454 }
455 456 if d.config.DecodeHook != nil {
457 // We have a DecodeHook, so let's pre-process the input.
458 var err error
459 input, err = DecodeHookExec(d.config.DecodeHook, inputVal, outVal)
460 if err != nil {
461 return fmt.Errorf("error decoding '%s': %s", name, err)
462 }
463 }
464 465 var err error
466 outputKind := getKind(outVal)
467 addMetaKey := true
468 switch outputKind {
469 case reflect.Bool:
470 err = d.decodeBool(name, input, outVal)
471 case reflect.Interface:
472 err = d.decodeBasic(name, input, outVal)
473 case reflect.String:
474 err = d.decodeString(name, input, outVal)
475 case reflect.Int:
476 err = d.decodeInt(name, input, outVal)
477 case reflect.Uint:
478 err = d.decodeUint(name, input, outVal)
479 case reflect.Float32:
480 err = d.decodeFloat(name, input, outVal)
481 case reflect.Struct:
482 err = d.decodeStruct(name, input, outVal)
483 case reflect.Map:
484 err = d.decodeMap(name, input, outVal)
485 case reflect.Ptr:
486 addMetaKey, err = d.decodePtr(name, input, outVal)
487 case reflect.Slice:
488 err = d.decodeSlice(name, input, outVal)
489 case reflect.Array:
490 err = d.decodeArray(name, input, outVal)
491 case reflect.Func:
492 err = d.decodeFunc(name, input, outVal)
493 default:
494 // If we reached this point then we weren't able to decode it
495 return fmt.Errorf("%s: unsupported type: %s", name, outputKind)
496 }
497 498 // If we reached here, then we successfully decoded SOMETHING, so
499 // mark the key as used if we're tracking metainput.
500 if addMetaKey && d.config.Metadata != nil && name != "" {
501 d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
502 }
503 504 return err
505 }
506 507 // This decodes a basic type (bool, int, string, etc.) and sets the
508 // value to "data" of that type.
509 func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error {
510 if val.IsValid() && val.Elem().IsValid() {
511 elem := val.Elem()
512 513 // If we can't address this element, then its not writable. Instead,
514 // we make a copy of the value (which is a pointer and therefore
515 // writable), decode into that, and replace the whole value.
516 copied := false
517 if !elem.CanAddr() {
518 copied = true
519 520 // Make *T
521 copy := reflect.New(elem.Type())
522 523 // *T = elem
524 copy.Elem().Set(elem)
525 526 // Set elem so we decode into it
527 elem = copy
528 }
529 530 // Decode. If we have an error then return. We also return right
531 // away if we're not a copy because that means we decoded directly.
532 if err := d.decode(name, data, elem); err != nil || !copied {
533 return err
534 }
535 536 // If we're a copy, we need to set te final result
537 val.Set(elem.Elem())
538 return nil
539 }
540 541 dataVal := reflect.ValueOf(data)
542 543 // If the input data is a pointer, and the assigned type is the dereference
544 // of that exact pointer, then indirect it so that we can assign it.
545 // Example: *string to string
546 if dataVal.Kind() == reflect.Ptr && dataVal.Type().Elem() == val.Type() {
547 dataVal = reflect.Indirect(dataVal)
548 }
549 550 if !dataVal.IsValid() {
551 dataVal = reflect.Zero(val.Type())
552 }
553 554 dataValType := dataVal.Type()
555 if !dataValType.AssignableTo(val.Type()) {
556 return fmt.Errorf(
557 "'%s' expected type '%s', got '%s'",
558 name, val.Type(), dataValType)
559 }
560 561 val.Set(dataVal)
562 return nil
563 }
564 565 func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) error {
566 dataVal := reflect.Indirect(reflect.ValueOf(data))
567 dataKind := getKind(dataVal)
568 569 converted := true
570 switch {
571 case dataKind == reflect.String:
572 val.SetString(dataVal.String())
573 case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
574 if dataVal.Bool() {
575 val.SetString("1")
576 } else {
577 val.SetString("0")
578 }
579 case dataKind == reflect.Int && d.config.WeaklyTypedInput:
580 val.SetString(strconv.FormatInt(dataVal.Int(), 10))
581 case dataKind == reflect.Uint && d.config.WeaklyTypedInput:
582 val.SetString(strconv.FormatUint(dataVal.Uint(), 10))
583 case dataKind == reflect.Float32 && d.config.WeaklyTypedInput:
584 val.SetString(strconv.FormatFloat(dataVal.Float(), 'f', -1, 64))
585 case dataKind == reflect.Slice && d.config.WeaklyTypedInput,
586 dataKind == reflect.Array && d.config.WeaklyTypedInput:
587 dataType := dataVal.Type()
588 elemKind := dataType.Elem().Kind()
589 switch elemKind {
590 case reflect.Uint8:
591 var uints []uint8
592 if dataKind == reflect.Array {
593 uints = make([]uint8, dataVal.Len(), dataVal.Len())
594 for i := range uints {
595 uints[i] = dataVal.Index(i).Interface().(uint8)
596 }
597 } else {
598 uints = dataVal.Interface().([]uint8)
599 }
600 val.SetString(string(uints))
601 default:
602 converted = false
603 }
604 default:
605 converted = false
606 }
607 608 if !converted {
609 return fmt.Errorf(
610 "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
611 name, val.Type(), dataVal.Type(), data)
612 }
613 614 return nil
615 }
616 617 func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) error {
618 dataVal := reflect.Indirect(reflect.ValueOf(data))
619 dataKind := getKind(dataVal)
620 dataType := dataVal.Type()
621 622 switch {
623 case dataKind == reflect.Int:
624 val.SetInt(dataVal.Int())
625 case dataKind == reflect.Uint:
626 val.SetInt(int64(dataVal.Uint()))
627 case dataKind == reflect.Float32:
628 val.SetInt(int64(dataVal.Float()))
629 case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
630 if dataVal.Bool() {
631 val.SetInt(1)
632 } else {
633 val.SetInt(0)
634 }
635 case dataKind == reflect.String && d.config.WeaklyTypedInput:
636 str := dataVal.String()
637 if str == "" {
638 str = "0"
639 }
640 641 i, err := strconv.ParseInt(str, 0, val.Type().Bits())
642 if err == nil {
643 val.SetInt(i)
644 } else {
645 return fmt.Errorf("cannot parse '%s' as int: %s", name, err)
646 }
647 case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
648 jn := data.(json.Number)
649 i, err := jn.Int64()
650 if err != nil {
651 return fmt.Errorf(
652 "error decoding json.Number into %s: %s", name, err)
653 }
654 val.SetInt(i)
655 default:
656 return fmt.Errorf(
657 "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
658 name, val.Type(), dataVal.Type(), data)
659 }
660 661 return nil
662 }
663 664 func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) error {
665 dataVal := reflect.Indirect(reflect.ValueOf(data))
666 dataKind := getKind(dataVal)
667 dataType := dataVal.Type()
668 669 switch {
670 case dataKind == reflect.Int:
671 i := dataVal.Int()
672 if i < 0 && !d.config.WeaklyTypedInput {
673 return fmt.Errorf("cannot parse '%s', %d overflows uint",
674 name, i)
675 }
676 val.SetUint(uint64(i))
677 case dataKind == reflect.Uint:
678 val.SetUint(dataVal.Uint())
679 case dataKind == reflect.Float32:
680 f := dataVal.Float()
681 if f < 0 && !d.config.WeaklyTypedInput {
682 return fmt.Errorf("cannot parse '%s', %f overflows uint",
683 name, f)
684 }
685 val.SetUint(uint64(f))
686 case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
687 if dataVal.Bool() {
688 val.SetUint(1)
689 } else {
690 val.SetUint(0)
691 }
692 case dataKind == reflect.String && d.config.WeaklyTypedInput:
693 str := dataVal.String()
694 if str == "" {
695 str = "0"
696 }
697 698 i, err := strconv.ParseUint(str, 0, val.Type().Bits())
699 if err == nil {
700 val.SetUint(i)
701 } else {
702 return fmt.Errorf("cannot parse '%s' as uint: %s", name, err)
703 }
704 case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
705 jn := data.(json.Number)
706 i, err := strconv.ParseUint(string(jn), 0, 64)
707 if err != nil {
708 return fmt.Errorf(
709 "error decoding json.Number into %s: %s", name, err)
710 }
711 val.SetUint(i)
712 default:
713 return fmt.Errorf(
714 "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
715 name, val.Type(), dataVal.Type(), data)
716 }
717 718 return nil
719 }
720 721 func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) error {
722 dataVal := reflect.Indirect(reflect.ValueOf(data))
723 dataKind := getKind(dataVal)
724 725 switch {
726 case dataKind == reflect.Bool:
727 val.SetBool(dataVal.Bool())
728 case dataKind == reflect.Int && d.config.WeaklyTypedInput:
729 val.SetBool(dataVal.Int() != 0)
730 case dataKind == reflect.Uint && d.config.WeaklyTypedInput:
731 val.SetBool(dataVal.Uint() != 0)
732 case dataKind == reflect.Float32 && d.config.WeaklyTypedInput:
733 val.SetBool(dataVal.Float() != 0)
734 case dataKind == reflect.String && d.config.WeaklyTypedInput:
735 b, err := strconv.ParseBool(dataVal.String())
736 if err == nil {
737 val.SetBool(b)
738 } else if dataVal.String() == "" {
739 val.SetBool(false)
740 } else {
741 return fmt.Errorf("cannot parse '%s' as bool: %s", name, err)
742 }
743 default:
744 return fmt.Errorf(
745 "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
746 name, val.Type(), dataVal.Type(), data)
747 }
748 749 return nil
750 }
751 752 func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) error {
753 dataVal := reflect.Indirect(reflect.ValueOf(data))
754 dataKind := getKind(dataVal)
755 dataType := dataVal.Type()
756 757 switch {
758 case dataKind == reflect.Int:
759 val.SetFloat(float64(dataVal.Int()))
760 case dataKind == reflect.Uint:
761 val.SetFloat(float64(dataVal.Uint()))
762 case dataKind == reflect.Float32:
763 val.SetFloat(dataVal.Float())
764 case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
765 if dataVal.Bool() {
766 val.SetFloat(1)
767 } else {
768 val.SetFloat(0)
769 }
770 case dataKind == reflect.String && d.config.WeaklyTypedInput:
771 str := dataVal.String()
772 if str == "" {
773 str = "0"
774 }
775 776 f, err := strconv.ParseFloat(str, val.Type().Bits())
777 if err == nil {
778 val.SetFloat(f)
779 } else {
780 return fmt.Errorf("cannot parse '%s' as float: %s", name, err)
781 }
782 case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
783 jn := data.(json.Number)
784 i, err := jn.Float64()
785 if err != nil {
786 return fmt.Errorf(
787 "error decoding json.Number into %s: %s", name, err)
788 }
789 val.SetFloat(i)
790 default:
791 return fmt.Errorf(
792 "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
793 name, val.Type(), dataVal.Type(), data)
794 }
795 796 return nil
797 }
798 799 func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) error {
800 valType := val.Type()
801 valKeyType := valType.Key()
802 valElemType := valType.Elem()
803 804 // By default we overwrite keys in the current map
805 valMap := val
806 807 // If the map is nil or we're purposely zeroing fields, make a new map
808 if valMap.IsNil() || d.config.ZeroFields {
809 // Make a new map to hold our result
810 mapType := reflect.MapOf(valKeyType, valElemType)
811 valMap = reflect.MakeMap(mapType)
812 }
813 814 // Check input type and based on the input type jump to the proper func
815 dataVal := reflect.Indirect(reflect.ValueOf(data))
816 switch dataVal.Kind() {
817 case reflect.Map:
818 return d.decodeMapFromMap(name, dataVal, val, valMap)
819 820 case reflect.Struct:
821 return d.decodeMapFromStruct(name, dataVal, val, valMap)
822 823 case reflect.Array, reflect.Slice:
824 if d.config.WeaklyTypedInput {
825 return d.decodeMapFromSlice(name, dataVal, val, valMap)
826 }
827 828 fallthrough
829 830 default:
831 return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind())
832 }
833 }
834 835 func (d *Decoder) decodeMapFromSlice(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {
836 // Special case for BC reasons (covered by tests)
837 if dataVal.Len() == 0 {
838 val.Set(valMap)
839 return nil
840 }
841 842 for i := 0; i < dataVal.Len(); i++ {
843 err := d.decode(
844 name+"["+strconv.Itoa(i)+"]",
845 dataVal.Index(i).Interface(), val)
846 if err != nil {
847 return err
848 }
849 }
850 851 return nil
852 }
853 854 func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {
855 valType := val.Type()
856 valKeyType := valType.Key()
857 valElemType := valType.Elem()
858 859 // Accumulate errors
860 errors := make([]string, 0)
861 862 // If the input data is empty, then we just match what the input data is.
863 if dataVal.Len() == 0 {
864 if dataVal.IsNil() {
865 if !val.IsNil() {
866 val.Set(dataVal)
867 }
868 } else {
869 // Set to empty allocated value
870 val.Set(valMap)
871 }
872 873 return nil
874 }
875 876 for _, k := range dataVal.MapKeys() {
877 fieldName := name + "[" + k.String() + "]"
878 879 // First decode the key into the proper type
880 currentKey := reflect.Indirect(reflect.New(valKeyType))
881 if err := d.decode(fieldName, k.Interface(), currentKey); err != nil {
882 errors = appendErrors(errors, err)
883 continue
884 }
885 886 // Next decode the data into the proper type
887 v := dataVal.MapIndex(k).Interface()
888 currentVal := reflect.Indirect(reflect.New(valElemType))
889 if err := d.decode(fieldName, v, currentVal); err != nil {
890 errors = appendErrors(errors, err)
891 continue
892 }
893 894 valMap.SetMapIndex(currentKey, currentVal)
895 }
896 897 // Set the built up map to the value
898 val.Set(valMap)
899 900 // If we had errors, return those
901 if len(errors) > 0 {
902 return &Error{errors}
903 }
904 905 return nil
906 }
907 908 func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {
909 typ := dataVal.Type()
910 for i := 0; i < typ.NumField(); i++ {
911 // Get the StructField first since this is a cheap operation. If the
912 // field is unexported, then ignore it.
913 f := typ.Field(i)
914 if f.PkgPath != "" {
915 continue
916 }
917 918 // Next get the actual value of this field and verify it is assignable
919 // to the map value.
920 v := dataVal.Field(i)
921 if !v.Type().AssignableTo(valMap.Type().Elem()) {
922 return fmt.Errorf("cannot assign type '%s' to map value field of type '%s'", v.Type(), valMap.Type().Elem())
923 }
924 925 tagValue := f.Tag.Get(d.config.TagName)
926 keyName := f.Name
927 928 if tagValue == "" && d.config.IgnoreUntaggedFields {
929 continue
930 }
931 932 // If Squash is set in the config, we squash the field down.
933 squash := d.config.Squash && v.Kind() == reflect.Struct && f.Anonymous
934 935 v = dereferencePtrToStructIfNeeded(v, d.config.TagName)
936 937 // Determine the name of the key in the map
938 if index := strings.Index(tagValue, ","); index != -1 {
939 if tagValue[:index] == "-" {
940 continue
941 }
942 // If "omitempty" is specified in the tag, it ignores empty values.
943 if strings.Index(tagValue[index+1:], "omitempty") != -1 && isEmptyValue(v) {
944 continue
945 }
946 947 // If "squash" is specified in the tag, we squash the field down.
948 squash = squash || strings.Index(tagValue[index+1:], "squash") != -1
949 if squash {
950 // When squashing, the embedded type can be a pointer to a struct.
951 if v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct {
952 v = v.Elem()
953 }
954 955 // The final type must be a struct
956 if v.Kind() != reflect.Struct {
957 return fmt.Errorf("cannot squash non-struct type '%s'", v.Type())
958 }
959 }
960 if keyNameTagValue := tagValue[:index]; keyNameTagValue != "" {
961 keyName = keyNameTagValue
962 }
963 } else if len(tagValue) > 0 {
964 if tagValue == "-" {
965 continue
966 }
967 keyName = tagValue
968 }
969 970 switch v.Kind() {
971 // this is an embedded struct, so handle it differently
972 case reflect.Struct:
973 x := reflect.New(v.Type())
974 x.Elem().Set(v)
975 976 vType := valMap.Type()
977 vKeyType := vType.Key()
978 vElemType := vType.Elem()
979 mType := reflect.MapOf(vKeyType, vElemType)
980 vMap := reflect.MakeMap(mType)
981 982 // Creating a pointer to a map so that other methods can completely
983 // overwrite the map if need be (looking at you decodeMapFromMap). The
984 // indirection allows the underlying map to be settable (CanSet() == true)
985 // where as reflect.MakeMap returns an unsettable map.
986 addrVal := reflect.New(vMap.Type())
987 reflect.Indirect(addrVal).Set(vMap)
988 989 err := d.decode(keyName, x.Interface(), reflect.Indirect(addrVal))
990 if err != nil {
991 return err
992 }
993 994 // the underlying map may have been completely overwritten so pull
995 // it indirectly out of the enclosing value.
996 vMap = reflect.Indirect(addrVal)
997 998 if squash {
999 for _, k := range vMap.MapKeys() {
1000 valMap.SetMapIndex(k, vMap.MapIndex(k))
1001 }
1002 } else {
1003 valMap.SetMapIndex(reflect.ValueOf(keyName), vMap)
1004 }
1005 1006 default:
1007 valMap.SetMapIndex(reflect.ValueOf(keyName), v)
1008 }
1009 }
1010 1011 if val.CanAddr() {
1012 val.Set(valMap)
1013 }
1014 1015 return nil
1016 }
1017 1018 func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) (bool, error) {
1019 // If the input data is nil, then we want to just set the output
1020 // pointer to be nil as well.
1021 isNil := data == nil
1022 if !isNil {
1023 switch v := reflect.Indirect(reflect.ValueOf(data)); v.Kind() {
1024 case reflect.Chan,
1025 reflect.Func,
1026 reflect.Interface,
1027 reflect.Map,
1028 reflect.Ptr,
1029 reflect.Slice:
1030 isNil = v.IsNil()
1031 }
1032 }
1033 if isNil {
1034 if !val.IsNil() && val.CanSet() {
1035 nilValue := reflect.New(val.Type()).Elem()
1036 val.Set(nilValue)
1037 }
1038 1039 return true, nil
1040 }
1041 1042 // Create an element of the concrete (non pointer) type and decode
1043 // into that. Then set the value of the pointer to this type.
1044 valType := val.Type()
1045 valElemType := valType.Elem()
1046 if val.CanSet() {
1047 realVal := val
1048 if realVal.IsNil() || d.config.ZeroFields {
1049 realVal = reflect.New(valElemType)
1050 }
1051 1052 if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil {
1053 return false, err
1054 }
1055 1056 val.Set(realVal)
1057 } else {
1058 if err := d.decode(name, data, reflect.Indirect(val)); err != nil {
1059 return false, err
1060 }
1061 }
1062 return false, nil
1063 }
1064 1065 func (d *Decoder) decodeFunc(name string, data interface{}, val reflect.Value) error {
1066 // Create an element of the concrete (non pointer) type and decode
1067 // into that. Then set the value of the pointer to this type.
1068 dataVal := reflect.Indirect(reflect.ValueOf(data))
1069 if val.Type() != dataVal.Type() {
1070 return fmt.Errorf(
1071 "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
1072 name, val.Type(), dataVal.Type(), data)
1073 }
1074 val.Set(dataVal)
1075 return nil
1076 }
1077 1078 func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error {
1079 dataVal := reflect.Indirect(reflect.ValueOf(data))
1080 dataValKind := dataVal.Kind()
1081 valType := val.Type()
1082 valElemType := valType.Elem()
1083 sliceType := reflect.SliceOf(valElemType)
1084 1085 // If we have a non array/slice type then we first attempt to convert.
1086 if dataValKind != reflect.Array && dataValKind != reflect.Slice {
1087 if d.config.WeaklyTypedInput {
1088 switch {
1089 // Slice and array we use the normal logic
1090 case dataValKind == reflect.Slice, dataValKind == reflect.Array:
1091 break
1092 1093 // Empty maps turn into empty slices
1094 case dataValKind == reflect.Map:
1095 if dataVal.Len() == 0 {
1096 val.Set(reflect.MakeSlice(sliceType, 0, 0))
1097 return nil
1098 }
1099 // Create slice of maps of other sizes
1100 return d.decodeSlice(name, []interface{}{data}, val)
1101 1102 case dataValKind == reflect.String && valElemType.Kind() == reflect.Uint8:
1103 return d.decodeSlice(name, []byte(dataVal.String()), val)
1104 1105 // All other types we try to convert to the slice type
1106 // and "lift" it into it. i.e. a string becomes a string slice.
1107 default:
1108 // Just re-try this function with data as a slice.
1109 return d.decodeSlice(name, []interface{}{data}, val)
1110 }
1111 }
1112 1113 return fmt.Errorf(
1114 "'%s': source data must be an array or slice, got %s", name, dataValKind)
1115 }
1116 1117 // If the input value is nil, then don't allocate since empty != nil
1118 if dataValKind != reflect.Array && dataVal.IsNil() {
1119 return nil
1120 }
1121 1122 valSlice := val
1123 if valSlice.IsNil() || d.config.ZeroFields {
1124 // Make a new slice to hold our result, same size as the original data.
1125 valSlice = reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len())
1126 }
1127 1128 // Accumulate any errors
1129 errors := make([]string, 0)
1130 1131 for i := 0; i < dataVal.Len(); i++ {
1132 currentData := dataVal.Index(i).Interface()
1133 for valSlice.Len() <= i {
1134 valSlice = reflect.Append(valSlice, reflect.Zero(valElemType))
1135 }
1136 currentField := valSlice.Index(i)
1137 1138 fieldName := name + "[" + strconv.Itoa(i) + "]"
1139 if err := d.decode(fieldName, currentData, currentField); err != nil {
1140 errors = appendErrors(errors, err)
1141 }
1142 }
1143 1144 // Finally, set the value to the slice we built up
1145 val.Set(valSlice)
1146 1147 // If there were errors, we return those
1148 if len(errors) > 0 {
1149 return &Error{errors}
1150 }
1151 1152 return nil
1153 }
1154 1155 func (d *Decoder) decodeArray(name string, data interface{}, val reflect.Value) error {
1156 dataVal := reflect.Indirect(reflect.ValueOf(data))
1157 dataValKind := dataVal.Kind()
1158 valType := val.Type()
1159 valElemType := valType.Elem()
1160 arrayType := reflect.ArrayOf(valType.Len(), valElemType)
1161 1162 valArray := val
1163 1164 if valArray.Interface() == reflect.Zero(valArray.Type()).Interface() || d.config.ZeroFields {
1165 // Check input type
1166 if dataValKind != reflect.Array && dataValKind != reflect.Slice {
1167 if d.config.WeaklyTypedInput {
1168 switch {
1169 // Empty maps turn into empty arrays
1170 case dataValKind == reflect.Map:
1171 if dataVal.Len() == 0 {
1172 val.Set(reflect.Zero(arrayType))
1173 return nil
1174 }
1175 1176 // All other types we try to convert to the array type
1177 // and "lift" it into it. i.e. a string becomes a string array.
1178 default:
1179 // Just re-try this function with data as a slice.
1180 return d.decodeArray(name, []interface{}{data}, val)
1181 }
1182 }
1183 1184 return fmt.Errorf(
1185 "'%s': source data must be an array or slice, got %s", name, dataValKind)
1186 1187 }
1188 if dataVal.Len() > arrayType.Len() {
1189 return fmt.Errorf(
1190 "'%s': expected source data to have length less or equal to %d, got %d", name, arrayType.Len(), dataVal.Len())
1191 1192 }
1193 1194 // Make a new array to hold our result, same size as the original data.
1195 valArray = reflect.New(arrayType).Elem()
1196 }
1197 1198 // Accumulate any errors
1199 errors := make([]string, 0)
1200 1201 for i := 0; i < dataVal.Len(); i++ {
1202 currentData := dataVal.Index(i).Interface()
1203 currentField := valArray.Index(i)
1204 1205 fieldName := name + "[" + strconv.Itoa(i) + "]"
1206 if err := d.decode(fieldName, currentData, currentField); err != nil {
1207 errors = appendErrors(errors, err)
1208 }
1209 }
1210 1211 // Finally, set the value to the array we built up
1212 val.Set(valArray)
1213 1214 // If there were errors, we return those
1215 if len(errors) > 0 {
1216 return &Error{errors}
1217 }
1218 1219 return nil
1220 }
1221 1222 func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) error {
1223 dataVal := reflect.Indirect(reflect.ValueOf(data))
1224 1225 // If the type of the value to write to and the data match directly,
1226 // then we just set it directly instead of recursing into the structure.
1227 if dataVal.Type() == val.Type() {
1228 val.Set(dataVal)
1229 return nil
1230 }
1231 1232 dataValKind := dataVal.Kind()
1233 switch dataValKind {
1234 case reflect.Map:
1235 return d.decodeStructFromMap(name, dataVal, val)
1236 1237 case reflect.Struct:
1238 // Not the most efficient way to do this but we can optimize later if
1239 // we want to. To convert from struct to struct we go to map first
1240 // as an intermediary.
1241 1242 // Make a new map to hold our result
1243 mapType := reflect.TypeOf((map[string]interface{})(nil))
1244 mval := reflect.MakeMap(mapType)
1245 1246 // Creating a pointer to a map so that other methods can completely
1247 // overwrite the map if need be (looking at you decodeMapFromMap). The
1248 // indirection allows the underlying map to be settable (CanSet() == true)
1249 // where as reflect.MakeMap returns an unsettable map.
1250 addrVal := reflect.New(mval.Type())
1251 1252 reflect.Indirect(addrVal).Set(mval)
1253 if err := d.decodeMapFromStruct(name, dataVal, reflect.Indirect(addrVal), mval); err != nil {
1254 return err
1255 }
1256 1257 result := d.decodeStructFromMap(name, reflect.Indirect(addrVal), val)
1258 return result
1259 1260 default:
1261 return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind())
1262 }
1263 }
1264 1265 func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) error {
1266 dataValType := dataVal.Type()
1267 if kind := dataValType.Key().Kind(); kind != reflect.String && kind != reflect.Interface {
1268 return fmt.Errorf(
1269 "'%s' needs a map with string keys, has '%s' keys",
1270 name, dataValType.Key().Kind())
1271 }
1272 1273 dataValKeys := make(map[reflect.Value]struct{})
1274 dataValKeysUnused := make(map[interface{}]struct{})
1275 for _, dataValKey := range dataVal.MapKeys() {
1276 dataValKeys[dataValKey] = struct{}{}
1277 dataValKeysUnused[dataValKey.Interface()] = struct{}{}
1278 }
1279 1280 targetValKeysUnused := make(map[interface{}]struct{})
1281 errors := make([]string, 0)
1282 1283 // This slice will keep track of all the structs we'll be decoding.
1284 // There can be more than one struct if there are embedded structs
1285 // that are squashed.
1286 structs := make([]reflect.Value, 1, 5)
1287 structs[0] = val
1288 1289 // Compile the list of all the fields that we're going to be decoding
1290 // from all the structs.
1291 type field struct {
1292 field reflect.StructField
1293 val reflect.Value
1294 }
1295 1296 // remainField is set to a valid field set with the "remain" tag if
1297 // we are keeping track of remaining values.
1298 var remainField *field
1299 1300 fields := []field{}
1301 for len(structs) > 0 {
1302 structVal := structs[0]
1303 structs = structs[1:]
1304 1305 structType := structVal.Type()
1306 1307 for i := 0; i < structType.NumField(); i++ {
1308 fieldType := structType.Field(i)
1309 fieldVal := structVal.Field(i)
1310 if fieldVal.Kind() == reflect.Ptr && fieldVal.Elem().Kind() == reflect.Struct {
1311 // Handle embedded struct pointers as embedded structs.
1312 fieldVal = fieldVal.Elem()
1313 }
1314 1315 // If "squash" is specified in the tag, we squash the field down.
1316 squash := d.config.Squash && fieldVal.Kind() == reflect.Struct && fieldType.Anonymous
1317 remain := false
1318 1319 // We always parse the tags cause we're looking for other tags too
1320 tagParts := strings.Split(fieldType.Tag.Get(d.config.TagName), ",")
1321 for _, tag := range tagParts[1:] {
1322 if tag == "squash" {
1323 squash = true
1324 break
1325 }
1326 1327 if tag == "remain" {
1328 remain = true
1329 break
1330 }
1331 }
1332 1333 if squash {
1334 if fieldVal.Kind() != reflect.Struct {
1335 errors = appendErrors(errors,
1336 fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldVal.Kind()))
1337 } else {
1338 structs = append(structs, fieldVal)
1339 }
1340 continue
1341 }
1342 1343 // Build our field
1344 if remain {
1345 remainField = &field{fieldType, fieldVal}
1346 } else {
1347 // Normal struct field, store it away
1348 fields = append(fields, field{fieldType, fieldVal})
1349 }
1350 }
1351 }
1352 1353 // for fieldType, field := range fields {
1354 for _, f := range fields {
1355 field, fieldValue := f.field, f.val
1356 fieldName := field.Name
1357 1358 tagValue := field.Tag.Get(d.config.TagName)
1359 tagValue = strings.SplitN(tagValue, ",", 2)[0]
1360 if tagValue != "" {
1361 fieldName = tagValue
1362 }
1363 1364 rawMapKey := reflect.ValueOf(fieldName)
1365 rawMapVal := dataVal.MapIndex(rawMapKey)
1366 if !rawMapVal.IsValid() {
1367 // Do a slower search by iterating over each key and
1368 // doing case-insensitive search.
1369 for dataValKey := range dataValKeys {
1370 mK, ok := dataValKey.Interface().(string)
1371 if !ok {
1372 // Not a string key
1373 continue
1374 }
1375 1376 if d.config.MatchName(mK, fieldName) {
1377 rawMapKey = dataValKey
1378 rawMapVal = dataVal.MapIndex(dataValKey)
1379 break
1380 }
1381 }
1382 1383 if !rawMapVal.IsValid() {
1384 // There was no matching key in the map for the value in
1385 // the struct. Remember it for potential errors and metadata.
1386 targetValKeysUnused[fieldName] = struct{}{}
1387 continue
1388 }
1389 }
1390 1391 if !fieldValue.IsValid() {
1392 // This should never happen
1393 panic("field is not valid")
1394 }
1395 1396 // If we can't set the field, then it is unexported or something,
1397 // and we just continue onwards.
1398 if !fieldValue.CanSet() {
1399 continue
1400 }
1401 1402 // Delete the key we're using from the unused map so we stop tracking
1403 delete(dataValKeysUnused, rawMapKey.Interface())
1404 1405 // If the name is empty string, then we're at the root, and we
1406 // don't dot-join the fields.
1407 if name != "" {
1408 fieldName = name + "." + fieldName
1409 }
1410 1411 if err := d.decode(fieldName, rawMapVal.Interface(), fieldValue); err != nil {
1412 errors = appendErrors(errors, err)
1413 }
1414 }
1415 1416 // If we have a "remain"-tagged field and we have unused keys then
1417 // we put the unused keys directly into the remain field.
1418 if remainField != nil && len(dataValKeysUnused) > 0 {
1419 // Build a map of only the unused values
1420 remain := map[interface{}]interface{}{}
1421 for key := range dataValKeysUnused {
1422 remain[key] = dataVal.MapIndex(reflect.ValueOf(key)).Interface()
1423 }
1424 1425 // Decode it as-if we were just decoding this map onto our map.
1426 if err := d.decodeMap(name, remain, remainField.val); err != nil {
1427 errors = appendErrors(errors, err)
1428 }
1429 1430 // Set the map to nil so we have none so that the next check will
1431 // not error (ErrorUnused)
1432 dataValKeysUnused = nil
1433 }
1434 1435 if d.config.ErrorUnused && len(dataValKeysUnused) > 0 {
1436 keys := make([]string, 0, len(dataValKeysUnused))
1437 for rawKey := range dataValKeysUnused {
1438 keys = append(keys, rawKey.(string))
1439 }
1440 sort.Strings(keys)
1441 1442 err := fmt.Errorf("'%s' has invalid keys: %s", name, strings.Join(keys, ", "))
1443 errors = appendErrors(errors, err)
1444 }
1445 1446 if d.config.ErrorUnset && len(targetValKeysUnused) > 0 {
1447 keys := make([]string, 0, len(targetValKeysUnused))
1448 for rawKey := range targetValKeysUnused {
1449 keys = append(keys, rawKey.(string))
1450 }
1451 sort.Strings(keys)
1452 1453 err := fmt.Errorf("'%s' has unset fields: %s", name, strings.Join(keys, ", "))
1454 errors = appendErrors(errors, err)
1455 }
1456 1457 if len(errors) > 0 {
1458 return &Error{errors}
1459 }
1460 1461 // Add the unused keys to the list of unused keys if we're tracking metadata
1462 if d.config.Metadata != nil {
1463 for rawKey := range dataValKeysUnused {
1464 key := rawKey.(string)
1465 if name != "" {
1466 key = name + "." + key
1467 }
1468 1469 d.config.Metadata.Unused = append(d.config.Metadata.Unused, key)
1470 }
1471 for rawKey := range targetValKeysUnused {
1472 key := rawKey.(string)
1473 if name != "" {
1474 key = name + "." + key
1475 }
1476 1477 d.config.Metadata.Unset = append(d.config.Metadata.Unset, key)
1478 }
1479 }
1480 1481 return nil
1482 }
1483 1484 func isEmptyValue(v reflect.Value) bool {
1485 switch getKind(v) {
1486 case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
1487 return v.Len() == 0
1488 case reflect.Bool:
1489 return !v.Bool()
1490 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
1491 return v.Int() == 0
1492 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
1493 return v.Uint() == 0
1494 case reflect.Float32, reflect.Float64:
1495 return v.Float() == 0
1496 case reflect.Interface, reflect.Ptr:
1497 return v.IsNil()
1498 }
1499 return false
1500 }
1501 1502 func getKind(val reflect.Value) reflect.Kind {
1503 kind := val.Kind()
1504 1505 switch {
1506 case kind >= reflect.Int && kind <= reflect.Int64:
1507 return reflect.Int
1508 case kind >= reflect.Uint && kind <= reflect.Uint64:
1509 return reflect.Uint
1510 case kind >= reflect.Float32 && kind <= reflect.Float64:
1511 return reflect.Float32
1512 default:
1513 return kind
1514 }
1515 }
1516 1517 func isStructTypeConvertibleToMap(typ reflect.Type, checkMapstructureTags bool, tagName string) bool {
1518 for i := 0; i < typ.NumField(); i++ {
1519 f := typ.Field(i)
1520 if f.PkgPath == "" && !checkMapstructureTags { // check for unexported fields
1521 return true
1522 }
1523 if checkMapstructureTags && f.Tag.Get(tagName) != "" { // check for mapstructure tags inside
1524 return true
1525 }
1526 }
1527 return false
1528 }
1529 1530 func dereferencePtrToStructIfNeeded(v reflect.Value, tagName string) reflect.Value {
1531 if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
1532 return v
1533 }
1534 deref := v.Elem()
1535 derefT := deref.Type()
1536 if isStructTypeConvertibleToMap(derefT, true, tagName) {
1537 return deref
1538 }
1539 return v
1540 }
1541