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