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