1// Package mapstructure exposes functionality to convert an arbitrary 2// map[string]interface{} into a native Go structure. 3// 4// The Go structure can be arbitrarily complex, containing slices, 5// other structs, etc. and the decoder will properly decode nested 6// maps and so on into the proper structures in the native Go struct. 7// See the examples to see what the decoder is capable of. 8package mapstructure 9 10import ( 11 "encoding/json" 12 "errors" 13 "fmt" 14 "reflect" 15 "sort" 16 "strconv" 17 "strings" 18) 19 20// DecodeHookFunc is the callback function that can be used for 21// data transformations. See "DecodeHook" in the DecoderConfig 22// struct. 23// 24// The type should be DecodeHookFuncType or DecodeHookFuncKind. 25// Either is accepted. Types are a superset of Kinds (Types can return 26// Kinds) and are generally a richer thing to use, but Kinds are simpler 27// if you only need those. 28// 29// The reason DecodeHookFunc is multi-typed is for backwards compatibility: 30// we started with Kinds and then realized Types were the better solution, 31// but have a promise to not break backwards compat so we now support 32// both. 33type DecodeHookFunc interface{} 34 35// DecodeHookFuncType is a DecodeHookFunc which has complete information about 36// the source and target types. 37type DecodeHookFuncType func(reflect.Type, reflect.Type, interface{}) (interface{}, error) 38 39// DecodeHookFuncKind is a DecodeHookFunc which knows only the Kinds of the 40// source and target types. 41type DecodeHookFuncKind func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error) 42 43// DecoderConfig is the configuration that is used to create a new decoder 44// and allows customization of various aspects of decoding. 45type DecoderConfig struct { 46 // DecodeHook, if set, will be called before any decoding and any 47 // type conversion (if WeaklyTypedInput is on). This lets you modify 48 // the values before they're set down onto the resulting struct. 49 // 50 // If an error is returned, the entire decode will fail with that 51 // error. 52 DecodeHook DecodeHookFunc 53 54 // If ErrorUnused is true, then it is an error for there to exist 55 // keys in the original map that were unused in the decoding process 56 // (extra keys). 57 ErrorUnused bool 58 59 // ZeroFields, if set to true, will zero fields before writing them. 60 // For example, a map will be emptied before decoded values are put in 61 // it. If this is false, a map will be merged. 62 ZeroFields bool 63 64 // If WeaklyTypedInput is true, the decoder will make the following 65 // "weak" conversions: 66 // 67 // - bools to string (true = "1", false = "0") 68 // - numbers to string (base 10) 69 // - bools to int/uint (true = 1, false = 0) 70 // - strings to int/uint (base implied by prefix) 71 // - int to bool (true if value != 0) 72 // - string to bool (accepts: 1, t, T, TRUE, true, True, 0, f, F, 73 // FALSE, false, False. Anything else is an error) 74 // - empty array = empty map and vice versa 75 // - negative numbers to overflowed uint values (base 10) 76 // - slice of maps to a merged map 77 // - single values are converted to slices if required. Each 78 // element is weakly decoded. For example: "4" can become []int{4} 79 // if the target type is an int slice. 80 // 81 WeaklyTypedInput bool 82 83 // Metadata is the struct that will contain extra metadata about 84 // the decoding. If this is nil, then no metadata will be tracked. 85 Metadata *Metadata 86 87 // Result is a pointer to the struct that will contain the decoded 88 // value. 89 Result interface{} 90 91 // The tag name that mapstructure reads for field names. This 92 // defaults to "mapstructure" 93 TagName string 94} 95 96// A Decoder takes a raw interface value and turns it into structured 97// data, keeping track of rich error information along the way in case 98// anything goes wrong. Unlike the basic top-level Decode method, you can 99// more finely control how the Decoder behaves using the DecoderConfig 100// structure. The top-level Decode method is just a convenience that sets 101// up the most basic Decoder. 102type Decoder struct { 103 config *DecoderConfig 104} 105 106// Metadata contains information about decoding a structure that 107// is tedious or difficult to get otherwise. 108type Metadata struct { 109 // Keys are the keys of the structure which were successfully decoded 110 Keys []string 111 112 // Unused is a slice of keys that were found in the raw value but 113 // weren't decoded since there was no matching field in the result interface 114 Unused []string 115} 116 117// Decode takes an input structure and uses reflection to translate it to 118// the output structure. output must be a pointer to a map or struct. 119func Decode(input interface{}, output interface{}) error { 120 config := &DecoderConfig{ 121 Metadata: nil, 122 Result: output, 123 } 124 125 decoder, err := NewDecoder(config) 126 if err != nil { 127 return err 128 } 129 130 return decoder.Decode(input) 131} 132 133// WeakDecode is the same as Decode but is shorthand to enable 134// WeaklyTypedInput. See DecoderConfig for more info. 135func WeakDecode(input, output interface{}) error { 136 config := &DecoderConfig{ 137 Metadata: nil, 138 Result: output, 139 WeaklyTypedInput: true, 140 } 141 142 decoder, err := NewDecoder(config) 143 if err != nil { 144 return err 145 } 146 147 return decoder.Decode(input) 148} 149 150// DecodeMetadata is the same as Decode, but is shorthand to 151// enable metadata collection. See DecoderConfig for more info. 152func DecodeMetadata(input interface{}, output interface{}, metadata *Metadata) error { 153 config := &DecoderConfig{ 154 Metadata: metadata, 155 Result: output, 156 } 157 158 decoder, err := NewDecoder(config) 159 if err != nil { 160 return err 161 } 162 163 return decoder.Decode(input) 164} 165 166// WeakDecodeMetadata is the same as Decode, but is shorthand to 167// enable both WeaklyTypedInput and metadata collection. See 168// DecoderConfig for more info. 169func WeakDecodeMetadata(input interface{}, output interface{}, metadata *Metadata) error { 170 config := &DecoderConfig{ 171 Metadata: metadata, 172 Result: output, 173 WeaklyTypedInput: true, 174 } 175 176 decoder, err := NewDecoder(config) 177 if err != nil { 178 return err 179 } 180 181 return decoder.Decode(input) 182} 183 184// NewDecoder returns a new decoder for the given configuration. Once 185// a decoder has been returned, the same configuration must not be used 186// again. 187func NewDecoder(config *DecoderConfig) (*Decoder, error) { 188 val := reflect.ValueOf(config.Result) 189 if val.Kind() != reflect.Ptr { 190 return nil, errors.New("result must be a pointer") 191 } 192 193 val = val.Elem() 194 if !val.CanAddr() { 195 return nil, errors.New("result must be addressable (a pointer)") 196 } 197 198 if config.Metadata != nil { 199 if config.Metadata.Keys == nil { 200 config.Metadata.Keys = make([]string, 0) 201 } 202 203 if config.Metadata.Unused == nil { 204 config.Metadata.Unused = make([]string, 0) 205 } 206 } 207 208 if config.TagName == "" { 209 config.TagName = "mapstructure" 210 } 211 212 result := &Decoder{ 213 config: config, 214 } 215 216 return result, nil 217} 218 219// Decode decodes the given raw interface to the target pointer specified 220// by the configuration. 221func (d *Decoder) Decode(input interface{}) error { 222 return d.decode("", input, reflect.ValueOf(d.config.Result).Elem()) 223} 224 225// Decodes an unknown data type into a specific reflection value. 226func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) error { 227 var inputVal reflect.Value 228 if input != nil { 229 inputVal = reflect.ValueOf(input) 230 231 // We need to check here if input is a typed nil. Typed nils won't 232 // match the "input == nil" below so we check that here. 233 if inputVal.Kind() == reflect.Ptr && inputVal.IsNil() { 234 input = nil 235 } 236 } 237 238 if input == nil { 239 // If the data is nil, then we don't set anything, unless ZeroFields is set 240 // to true. 241 if d.config.ZeroFields { 242 outVal.Set(reflect.Zero(outVal.Type())) 243 244 if d.config.Metadata != nil && name != "" { 245 d.config.Metadata.Keys = append(d.config.Metadata.Keys, name) 246 } 247 } 248 return nil 249 } 250 251 if !inputVal.IsValid() { 252 // If the input value is invalid, then we just set the value 253 // to be the zero value. 254 outVal.Set(reflect.Zero(outVal.Type())) 255 if d.config.Metadata != nil && name != "" { 256 d.config.Metadata.Keys = append(d.config.Metadata.Keys, name) 257 } 258 return nil 259 } 260 261 if d.config.DecodeHook != nil { 262 // We have a DecodeHook, so let's pre-process the input. 263 var err error 264 input, err = DecodeHookExec( 265 d.config.DecodeHook, 266 inputVal.Type(), outVal.Type(), input) 267 if err != nil { 268 return fmt.Errorf("error decoding '%s': %s", name, err) 269 } 270 } 271 272 var err error 273 outputKind := getKind(outVal) 274 switch outputKind { 275 case reflect.Bool: 276 err = d.decodeBool(name, input, outVal) 277 case reflect.Interface: 278 err = d.decodeBasic(name, input, outVal) 279 case reflect.String: 280 err = d.decodeString(name, input, outVal) 281 case reflect.Int: 282 err = d.decodeInt(name, input, outVal) 283 case reflect.Uint: 284 err = d.decodeUint(name, input, outVal) 285 case reflect.Float32: 286 err = d.decodeFloat(name, input, outVal) 287 case reflect.Struct: 288 err = d.decodeStruct(name, input, outVal) 289 case reflect.Map: 290 err = d.decodeMap(name, input, outVal) 291 case reflect.Ptr: 292 err = d.decodePtr(name, input, outVal) 293 case reflect.Slice: 294 err = d.decodeSlice(name, input, outVal) 295 case reflect.Array: 296 err = d.decodeArray(name, input, outVal) 297 case reflect.Func: 298 err = d.decodeFunc(name, input, outVal) 299 default: 300 // If we reached this point then we weren't able to decode it 301 return fmt.Errorf("%s: unsupported type: %s", name, outputKind) 302 } 303 304 // If we reached here, then we successfully decoded SOMETHING, so 305 // mark the key as used if we're tracking metainput. 306 if d.config.Metadata != nil && name != "" { 307 d.config.Metadata.Keys = append(d.config.Metadata.Keys, name) 308 } 309 310 return err 311} 312 313// This decodes a basic type (bool, int, string, etc.) and sets the 314// value to "data" of that type. 315func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error { 316 if val.IsValid() && val.Elem().IsValid() { 317 return d.decode(name, data, val.Elem()) 318 } 319 320 dataVal := reflect.ValueOf(data) 321 322 // If the input data is a pointer, and the assigned type is the dereference 323 // of that exact pointer, then indirect it so that we can assign it. 324 // Example: *string to string 325 if dataVal.Kind() == reflect.Ptr && dataVal.Type().Elem() == val.Type() { 326 dataVal = reflect.Indirect(dataVal) 327 } 328 329 if !dataVal.IsValid() { 330 dataVal = reflect.Zero(val.Type()) 331 } 332 333 dataValType := dataVal.Type() 334 if !dataValType.AssignableTo(val.Type()) { 335 return fmt.Errorf( 336 "'%s' expected type '%s', got '%s'", 337 name, val.Type(), dataValType) 338 } 339 340 val.Set(dataVal) 341 return nil 342} 343 344func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) error { 345 dataVal := reflect.Indirect(reflect.ValueOf(data)) 346 dataKind := getKind(dataVal) 347 348 converted := true 349 switch { 350 case dataKind == reflect.String: 351 val.SetString(dataVal.String()) 352 case dataKind == reflect.Bool && d.config.WeaklyTypedInput: 353 if dataVal.Bool() { 354 val.SetString("1") 355 } else { 356 val.SetString("0") 357 } 358 case dataKind == reflect.Int && d.config.WeaklyTypedInput: 359 val.SetString(strconv.FormatInt(dataVal.Int(), 10)) 360 case dataKind == reflect.Uint && d.config.WeaklyTypedInput: 361 val.SetString(strconv.FormatUint(dataVal.Uint(), 10)) 362 case dataKind == reflect.Float32 && d.config.WeaklyTypedInput: 363 val.SetString(strconv.FormatFloat(dataVal.Float(), 'f', -1, 64)) 364 case dataKind == reflect.Slice && d.config.WeaklyTypedInput, 365 dataKind == reflect.Array && d.config.WeaklyTypedInput: 366 dataType := dataVal.Type() 367 elemKind := dataType.Elem().Kind() 368 switch elemKind { 369 case reflect.Uint8: 370 var uints []uint8 371 if dataKind == reflect.Array { 372 uints = make([]uint8, dataVal.Len(), dataVal.Len()) 373 for i := range uints { 374 uints[i] = dataVal.Index(i).Interface().(uint8) 375 } 376 } else { 377 uints = dataVal.Interface().([]uint8) 378 } 379 val.SetString(string(uints)) 380 default: 381 converted = false 382 } 383 default: 384 converted = false 385 } 386 387 if !converted { 388 return fmt.Errorf( 389 "'%s' expected type '%s', got unconvertible type '%s'", 390 name, val.Type(), dataVal.Type()) 391 } 392 393 return nil 394} 395 396func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) error { 397 dataVal := reflect.Indirect(reflect.ValueOf(data)) 398 dataKind := getKind(dataVal) 399 dataType := dataVal.Type() 400 401 switch { 402 case dataKind == reflect.Int: 403 val.SetInt(dataVal.Int()) 404 case dataKind == reflect.Uint: 405 val.SetInt(int64(dataVal.Uint())) 406 case dataKind == reflect.Float32: 407 val.SetInt(int64(dataVal.Float())) 408 case dataKind == reflect.Bool && d.config.WeaklyTypedInput: 409 if dataVal.Bool() { 410 val.SetInt(1) 411 } else { 412 val.SetInt(0) 413 } 414 case dataKind == reflect.String && d.config.WeaklyTypedInput: 415 i, err := strconv.ParseInt(dataVal.String(), 0, val.Type().Bits()) 416 if err == nil { 417 val.SetInt(i) 418 } else { 419 return fmt.Errorf("cannot parse '%s' as int: %s", name, err) 420 } 421 case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number": 422 jn := data.(json.Number) 423 i, err := jn.Int64() 424 if err != nil { 425 return fmt.Errorf( 426 "error decoding json.Number into %s: %s", name, err) 427 } 428 val.SetInt(i) 429 default: 430 return fmt.Errorf( 431 "'%s' expected type '%s', got unconvertible type '%s'", 432 name, val.Type(), dataVal.Type()) 433 } 434 435 return nil 436} 437 438func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) error { 439 dataVal := reflect.Indirect(reflect.ValueOf(data)) 440 dataKind := getKind(dataVal) 441 442 switch { 443 case dataKind == reflect.Int: 444 i := dataVal.Int() 445 if i < 0 && !d.config.WeaklyTypedInput { 446 return fmt.Errorf("cannot parse '%s', %d overflows uint", 447 name, i) 448 } 449 val.SetUint(uint64(i)) 450 case dataKind == reflect.Uint: 451 val.SetUint(dataVal.Uint()) 452 case dataKind == reflect.Float32: 453 f := dataVal.Float() 454 if f < 0 && !d.config.WeaklyTypedInput { 455 return fmt.Errorf("cannot parse '%s', %f overflows uint", 456 name, f) 457 } 458 val.SetUint(uint64(f)) 459 case dataKind == reflect.Bool && d.config.WeaklyTypedInput: 460 if dataVal.Bool() { 461 val.SetUint(1) 462 } else { 463 val.SetUint(0) 464 } 465 case dataKind == reflect.String && d.config.WeaklyTypedInput: 466 i, err := strconv.ParseUint(dataVal.String(), 0, val.Type().Bits()) 467 if err == nil { 468 val.SetUint(i) 469 } else { 470 return fmt.Errorf("cannot parse '%s' as uint: %s", name, err) 471 } 472 default: 473 return fmt.Errorf( 474 "'%s' expected type '%s', got unconvertible type '%s'", 475 name, val.Type(), dataVal.Type()) 476 } 477 478 return nil 479} 480 481func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) error { 482 dataVal := reflect.Indirect(reflect.ValueOf(data)) 483 dataKind := getKind(dataVal) 484 485 switch { 486 case dataKind == reflect.Bool: 487 val.SetBool(dataVal.Bool()) 488 case dataKind == reflect.Int && d.config.WeaklyTypedInput: 489 val.SetBool(dataVal.Int() != 0) 490 case dataKind == reflect.Uint && d.config.WeaklyTypedInput: 491 val.SetBool(dataVal.Uint() != 0) 492 case dataKind == reflect.Float32 && d.config.WeaklyTypedInput: 493 val.SetBool(dataVal.Float() != 0) 494 case dataKind == reflect.String && d.config.WeaklyTypedInput: 495 b, err := strconv.ParseBool(dataVal.String()) 496 if err == nil { 497 val.SetBool(b) 498 } else if dataVal.String() == "" { 499 val.SetBool(false) 500 } else { 501 return fmt.Errorf("cannot parse '%s' as bool: %s", name, err) 502 } 503 default: 504 return fmt.Errorf( 505 "'%s' expected type '%s', got unconvertible type '%s'", 506 name, val.Type(), dataVal.Type()) 507 } 508 509 return nil 510} 511 512func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) error { 513 dataVal := reflect.Indirect(reflect.ValueOf(data)) 514 dataKind := getKind(dataVal) 515 dataType := dataVal.Type() 516 517 switch { 518 case dataKind == reflect.Int: 519 val.SetFloat(float64(dataVal.Int())) 520 case dataKind == reflect.Uint: 521 val.SetFloat(float64(dataVal.Uint())) 522 case dataKind == reflect.Float32: 523 val.SetFloat(dataVal.Float()) 524 case dataKind == reflect.Bool && d.config.WeaklyTypedInput: 525 if dataVal.Bool() { 526 val.SetFloat(1) 527 } else { 528 val.SetFloat(0) 529 } 530 case dataKind == reflect.String && d.config.WeaklyTypedInput: 531 f, err := strconv.ParseFloat(dataVal.String(), val.Type().Bits()) 532 if err == nil { 533 val.SetFloat(f) 534 } else { 535 return fmt.Errorf("cannot parse '%s' as float: %s", name, err) 536 } 537 case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number": 538 jn := data.(json.Number) 539 i, err := jn.Float64() 540 if err != nil { 541 return fmt.Errorf( 542 "error decoding json.Number into %s: %s", name, err) 543 } 544 val.SetFloat(i) 545 default: 546 return fmt.Errorf( 547 "'%s' expected type '%s', got unconvertible type '%s'", 548 name, val.Type(), dataVal.Type()) 549 } 550 551 return nil 552} 553 554func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) error { 555 valType := val.Type() 556 valKeyType := valType.Key() 557 valElemType := valType.Elem() 558 559 // By default we overwrite keys in the current map 560 valMap := val 561 562 // If the map is nil or we're purposely zeroing fields, make a new map 563 if valMap.IsNil() || d.config.ZeroFields { 564 // Make a new map to hold our result 565 mapType := reflect.MapOf(valKeyType, valElemType) 566 valMap = reflect.MakeMap(mapType) 567 } 568 569 // Check input type and based on the input type jump to the proper func 570 dataVal := reflect.Indirect(reflect.ValueOf(data)) 571 switch dataVal.Kind() { 572 case reflect.Map: 573 return d.decodeMapFromMap(name, dataVal, val, valMap) 574 575 case reflect.Struct: 576 return d.decodeMapFromStruct(name, dataVal, val, valMap) 577 578 case reflect.Array, reflect.Slice: 579 if d.config.WeaklyTypedInput { 580 return d.decodeMapFromSlice(name, dataVal, val, valMap) 581 } 582 583 fallthrough 584 585 default: 586 return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind()) 587 } 588} 589 590func (d *Decoder) decodeMapFromSlice(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error { 591 // Special case for BC reasons (covered by tests) 592 if dataVal.Len() == 0 { 593 val.Set(valMap) 594 return nil 595 } 596 597 for i := 0; i < dataVal.Len(); i++ { 598 err := d.decode( 599 fmt.Sprintf("%s[%d]", name, i), 600 dataVal.Index(i).Interface(), val) 601 if err != nil { 602 return err 603 } 604 } 605 606 return nil 607} 608 609func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error { 610 valType := val.Type() 611 valKeyType := valType.Key() 612 valElemType := valType.Elem() 613 614 // Accumulate errors 615 errors := make([]string, 0) 616 617 // If the input data is empty, then we just match what the input data is. 618 if dataVal.Len() == 0 { 619 if dataVal.IsNil() { 620 if !val.IsNil() { 621 val.Set(dataVal) 622 } 623 } else { 624 // Set to empty allocated value 625 val.Set(valMap) 626 } 627 628 return nil 629 } 630 631 for _, k := range dataVal.MapKeys() { 632 fieldName := fmt.Sprintf("%s[%s]", name, k) 633 634 // First decode the key into the proper type 635 currentKey := reflect.Indirect(reflect.New(valKeyType)) 636 if err := d.decode(fieldName, k.Interface(), currentKey); err != nil { 637 errors = appendErrors(errors, err) 638 continue 639 } 640 641 // Next decode the data into the proper type 642 v := dataVal.MapIndex(k).Interface() 643 currentVal := reflect.Indirect(reflect.New(valElemType)) 644 if err := d.decode(fieldName, v, currentVal); err != nil { 645 errors = appendErrors(errors, err) 646 continue 647 } 648 649 valMap.SetMapIndex(currentKey, currentVal) 650 } 651 652 // Set the built up map to the value 653 val.Set(valMap) 654 655 // If we had errors, return those 656 if len(errors) > 0 { 657 return &Error{errors} 658 } 659 660 return nil 661} 662 663func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error { 664 typ := dataVal.Type() 665 for i := 0; i < typ.NumField(); i++ { 666 // Get the StructField first since this is a cheap operation. If the 667 // field is unexported, then ignore it. 668 f := typ.Field(i) 669 if f.PkgPath != "" { 670 continue 671 } 672 673 // Next get the actual value of this field and verify it is assignable 674 // to the map value. 675 v := dataVal.Field(i) 676 if !v.Type().AssignableTo(valMap.Type().Elem()) { 677 return fmt.Errorf("cannot assign type '%s' to map value field of type '%s'", v.Type(), valMap.Type().Elem()) 678 } 679 680 tagValue := f.Tag.Get(d.config.TagName) 681 tagParts := strings.Split(tagValue, ",") 682 683 // Determine the name of the key in the map 684 keyName := f.Name 685 if tagParts[0] != "" { 686 if tagParts[0] == "-" { 687 continue 688 } 689 keyName = tagParts[0] 690 } 691 692 // If "squash" is specified in the tag, we squash the field down. 693 squash := false 694 for _, tag := range tagParts[1:] { 695 if tag == "squash" { 696 squash = true 697 break 698 } 699 } 700 if squash && v.Kind() != reflect.Struct { 701 return fmt.Errorf("cannot squash non-struct type '%s'", v.Type()) 702 } 703 704 switch v.Kind() { 705 // this is an embedded struct, so handle it differently 706 case reflect.Struct: 707 x := reflect.New(v.Type()) 708 x.Elem().Set(v) 709 710 vType := valMap.Type() 711 vKeyType := vType.Key() 712 vElemType := vType.Elem() 713 mType := reflect.MapOf(vKeyType, vElemType) 714 vMap := reflect.MakeMap(mType) 715 716 err := d.decode(keyName, x.Interface(), vMap) 717 if err != nil { 718 return err 719 } 720 721 if squash { 722 for _, k := range vMap.MapKeys() { 723 valMap.SetMapIndex(k, vMap.MapIndex(k)) 724 } 725 } else { 726 valMap.SetMapIndex(reflect.ValueOf(keyName), vMap) 727 } 728 729 default: 730 valMap.SetMapIndex(reflect.ValueOf(keyName), v) 731 } 732 } 733 734 if val.CanAddr() { 735 val.Set(valMap) 736 } 737 738 return nil 739} 740 741func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) error { 742 // If the input data is nil, then we want to just set the output 743 // pointer to be nil as well. 744 isNil := data == nil 745 if !isNil { 746 switch v := reflect.Indirect(reflect.ValueOf(data)); v.Kind() { 747 case reflect.Chan, 748 reflect.Func, 749 reflect.Interface, 750 reflect.Map, 751 reflect.Ptr, 752 reflect.Slice: 753 isNil = v.IsNil() 754 } 755 } 756 if isNil { 757 if !val.IsNil() && val.CanSet() { 758 nilValue := reflect.New(val.Type()).Elem() 759 val.Set(nilValue) 760 } 761 762 return nil 763 } 764 765 // Create an element of the concrete (non pointer) type and decode 766 // into that. Then set the value of the pointer to this type. 767 valType := val.Type() 768 valElemType := valType.Elem() 769 if val.CanSet() { 770 realVal := val 771 if realVal.IsNil() || d.config.ZeroFields { 772 realVal = reflect.New(valElemType) 773 } 774 775 if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil { 776 return err 777 } 778 779 val.Set(realVal) 780 } else { 781 if err := d.decode(name, data, reflect.Indirect(val)); err != nil { 782 return err 783 } 784 } 785 return nil 786} 787 788func (d *Decoder) decodeFunc(name string, data interface{}, val reflect.Value) error { 789 // Create an element of the concrete (non pointer) type and decode 790 // into that. Then set the value of the pointer to this type. 791 dataVal := reflect.Indirect(reflect.ValueOf(data)) 792 if val.Type() != dataVal.Type() { 793 return fmt.Errorf( 794 "'%s' expected type '%s', got unconvertible type '%s'", 795 name, val.Type(), dataVal.Type()) 796 } 797 val.Set(dataVal) 798 return nil 799} 800 801func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error { 802 dataVal := reflect.Indirect(reflect.ValueOf(data)) 803 dataValKind := dataVal.Kind() 804 valType := val.Type() 805 valElemType := valType.Elem() 806 sliceType := reflect.SliceOf(valElemType) 807 808 valSlice := val 809 if valSlice.IsNil() || d.config.ZeroFields { 810 if d.config.WeaklyTypedInput { 811 switch { 812 // Slice and array we use the normal logic 813 case dataValKind == reflect.Slice, dataValKind == reflect.Array: 814 break 815 816 // Empty maps turn into empty slices 817 case dataValKind == reflect.Map: 818 if dataVal.Len() == 0 { 819 val.Set(reflect.MakeSlice(sliceType, 0, 0)) 820 return nil 821 } 822 // Create slice of maps of other sizes 823 return d.decodeSlice(name, []interface{}{data}, val) 824 825 case dataValKind == reflect.String && valElemType.Kind() == reflect.Uint8: 826 return d.decodeSlice(name, []byte(dataVal.String()), val) 827 828 // All other types we try to convert to the slice type 829 // and "lift" it into it. i.e. a string becomes a string slice. 830 default: 831 // Just re-try this function with data as a slice. 832 return d.decodeSlice(name, []interface{}{data}, val) 833 } 834 } 835 836 // Check input type 837 if dataValKind != reflect.Array && dataValKind != reflect.Slice { 838 return fmt.Errorf( 839 "'%s': source data must be an array or slice, got %s", name, dataValKind) 840 841 } 842 843 // If the input value is empty, then don't allocate since non-nil != nil 844 if dataVal.Len() == 0 { 845 return nil 846 } 847 848 // Make a new slice to hold our result, same size as the original data. 849 valSlice = reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len()) 850 } 851 852 // Accumulate any errors 853 errors := make([]string, 0) 854 855 for i := 0; i < dataVal.Len(); i++ { 856 currentData := dataVal.Index(i).Interface() 857 for valSlice.Len() <= i { 858 valSlice = reflect.Append(valSlice, reflect.Zero(valElemType)) 859 } 860 currentField := valSlice.Index(i) 861 862 fieldName := fmt.Sprintf("%s[%d]", name, i) 863 if err := d.decode(fieldName, currentData, currentField); err != nil { 864 errors = appendErrors(errors, err) 865 } 866 } 867 868 // Finally, set the value to the slice we built up 869 val.Set(valSlice) 870 871 // If there were errors, we return those 872 if len(errors) > 0 { 873 return &Error{errors} 874 } 875 876 return nil 877} 878 879func (d *Decoder) decodeArray(name string, data interface{}, val reflect.Value) error { 880 dataVal := reflect.Indirect(reflect.ValueOf(data)) 881 dataValKind := dataVal.Kind() 882 valType := val.Type() 883 valElemType := valType.Elem() 884 arrayType := reflect.ArrayOf(valType.Len(), valElemType) 885 886 valArray := val 887 888 if valArray.Interface() == reflect.Zero(valArray.Type()).Interface() || d.config.ZeroFields { 889 // Check input type 890 if dataValKind != reflect.Array && dataValKind != reflect.Slice { 891 if d.config.WeaklyTypedInput { 892 switch { 893 // Empty maps turn into empty arrays 894 case dataValKind == reflect.Map: 895 if dataVal.Len() == 0 { 896 val.Set(reflect.Zero(arrayType)) 897 return nil 898 } 899 900 // All other types we try to convert to the array type 901 // and "lift" it into it. i.e. a string becomes a string array. 902 default: 903 // Just re-try this function with data as a slice. 904 return d.decodeArray(name, []interface{}{data}, val) 905 } 906 } 907 908 return fmt.Errorf( 909 "'%s': source data must be an array or slice, got %s", name, dataValKind) 910 911 } 912 if dataVal.Len() > arrayType.Len() { 913 return fmt.Errorf( 914 "'%s': expected source data to have length less or equal to %d, got %d", name, arrayType.Len(), dataVal.Len()) 915 916 } 917 918 // Make a new array to hold our result, same size as the original data. 919 valArray = reflect.New(arrayType).Elem() 920 } 921 922 // Accumulate any errors 923 errors := make([]string, 0) 924 925 for i := 0; i < dataVal.Len(); i++ { 926 currentData := dataVal.Index(i).Interface() 927 currentField := valArray.Index(i) 928 929 fieldName := fmt.Sprintf("%s[%d]", name, i) 930 if err := d.decode(fieldName, currentData, currentField); err != nil { 931 errors = appendErrors(errors, err) 932 } 933 } 934 935 // Finally, set the value to the array we built up 936 val.Set(valArray) 937 938 // If there were errors, we return those 939 if len(errors) > 0 { 940 return &Error{errors} 941 } 942 943 return nil 944} 945 946func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) error { 947 dataVal := reflect.Indirect(reflect.ValueOf(data)) 948 949 // If the type of the value to write to and the data match directly, 950 // then we just set it directly instead of recursing into the structure. 951 if dataVal.Type() == val.Type() { 952 val.Set(dataVal) 953 return nil 954 } 955 956 dataValKind := dataVal.Kind() 957 switch dataValKind { 958 case reflect.Map: 959 return d.decodeStructFromMap(name, dataVal, val) 960 961 case reflect.Struct: 962 // Not the most efficient way to do this but we can optimize later if 963 // we want to. To convert from struct to struct we go to map first 964 // as an intermediary. 965 m := make(map[string]interface{}) 966 mval := reflect.Indirect(reflect.ValueOf(&m)) 967 if err := d.decodeMapFromStruct(name, dataVal, mval, mval); err != nil { 968 return err 969 } 970 971 result := d.decodeStructFromMap(name, mval, val) 972 return result 973 974 default: 975 return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind()) 976 } 977} 978 979func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) error { 980 dataValType := dataVal.Type() 981 if kind := dataValType.Key().Kind(); kind != reflect.String && kind != reflect.Interface { 982 return fmt.Errorf( 983 "'%s' needs a map with string keys, has '%s' keys", 984 name, dataValType.Key().Kind()) 985 } 986 987 dataValKeys := make(map[reflect.Value]struct{}) 988 dataValKeysUnused := make(map[interface{}]struct{}) 989 for _, dataValKey := range dataVal.MapKeys() { 990 dataValKeys[dataValKey] = struct{}{} 991 dataValKeysUnused[dataValKey.Interface()] = struct{}{} 992 } 993 994 errors := make([]string, 0) 995 996 // This slice will keep track of all the structs we'll be decoding. 997 // There can be more than one struct if there are embedded structs 998 // that are squashed. 999 structs := make([]reflect.Value, 1, 5) 1000 structs[0] = val 1001 1002 // Compile the list of all the fields that we're going to be decoding 1003 // from all the structs. 1004 type field struct { 1005 field reflect.StructField 1006 val reflect.Value 1007 } 1008 fields := []field{} 1009 for len(structs) > 0 { 1010 structVal := structs[0] 1011 structs = structs[1:] 1012 1013 structType := structVal.Type() 1014 1015 for i := 0; i < structType.NumField(); i++ { 1016 fieldType := structType.Field(i) 1017 fieldKind := fieldType.Type.Kind() 1018 1019 // If "squash" is specified in the tag, we squash the field down. 1020 squash := false 1021 tagParts := strings.Split(fieldType.Tag.Get(d.config.TagName), ",") 1022 for _, tag := range tagParts[1:] { 1023 if tag == "squash" { 1024 squash = true 1025 break 1026 } 1027 } 1028 1029 if squash { 1030 if fieldKind != reflect.Struct { 1031 errors = appendErrors(errors, 1032 fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldKind)) 1033 } else { 1034 structs = append(structs, structVal.FieldByName(fieldType.Name)) 1035 } 1036 continue 1037 } 1038 1039 // Normal struct field, store it away 1040 fields = append(fields, field{fieldType, structVal.Field(i)}) 1041 } 1042 } 1043 1044 // for fieldType, field := range fields { 1045 for _, f := range fields { 1046 field, fieldValue := f.field, f.val 1047 fieldName := field.Name 1048 1049 tagValue := field.Tag.Get(d.config.TagName) 1050 tagValue = strings.SplitN(tagValue, ",", 2)[0] 1051 if tagValue != "" { 1052 fieldName = tagValue 1053 } 1054 1055 rawMapKey := reflect.ValueOf(fieldName) 1056 rawMapVal := dataVal.MapIndex(rawMapKey) 1057 if !rawMapVal.IsValid() { 1058 // Do a slower search by iterating over each key and 1059 // doing case-insensitive search. 1060 for dataValKey := range dataValKeys { 1061 mK, ok := dataValKey.Interface().(string) 1062 if !ok { 1063 // Not a string key 1064 continue 1065 } 1066 1067 if strings.EqualFold(mK, fieldName) { 1068 rawMapKey = dataValKey 1069 rawMapVal = dataVal.MapIndex(dataValKey) 1070 break 1071 } 1072 } 1073 1074 if !rawMapVal.IsValid() { 1075 // There was no matching key in the map for the value in 1076 // the struct. Just ignore. 1077 continue 1078 } 1079 } 1080 1081 // Delete the key we're using from the unused map so we stop tracking 1082 delete(dataValKeysUnused, rawMapKey.Interface()) 1083 1084 if !fieldValue.IsValid() { 1085 // This should never happen 1086 panic("field is not valid") 1087 } 1088 1089 // If we can't set the field, then it is unexported or something, 1090 // and we just continue onwards. 1091 if !fieldValue.CanSet() { 1092 continue 1093 } 1094 1095 // If the name is empty string, then we're at the root, and we 1096 // don't dot-join the fields. 1097 if name != "" { 1098 fieldName = fmt.Sprintf("%s.%s", name, fieldName) 1099 } 1100 1101 if err := d.decode(fieldName, rawMapVal.Interface(), fieldValue); err != nil { 1102 errors = appendErrors(errors, err) 1103 } 1104 } 1105 1106 if d.config.ErrorUnused && len(dataValKeysUnused) > 0 { 1107 keys := make([]string, 0, len(dataValKeysUnused)) 1108 for rawKey := range dataValKeysUnused { 1109 keys = append(keys, rawKey.(string)) 1110 } 1111 sort.Strings(keys) 1112 1113 err := fmt.Errorf("'%s' has invalid keys: %s", name, strings.Join(keys, ", ")) 1114 errors = appendErrors(errors, err) 1115 } 1116 1117 if len(errors) > 0 { 1118 return &Error{errors} 1119 } 1120 1121 // Add the unused keys to the list of unused keys if we're tracking metadata 1122 if d.config.Metadata != nil { 1123 for rawKey := range dataValKeysUnused { 1124 key := rawKey.(string) 1125 if name != "" { 1126 key = fmt.Sprintf("%s.%s", name, key) 1127 } 1128 1129 d.config.Metadata.Unused = append(d.config.Metadata.Unused, key) 1130 } 1131 } 1132 1133 return nil 1134} 1135 1136func getKind(val reflect.Value) reflect.Kind { 1137 kind := val.Kind() 1138 1139 switch { 1140 case kind >= reflect.Int && kind <= reflect.Int64: 1141 return reflect.Int 1142 case kind >= reflect.Uint && kind <= reflect.Uint64: 1143 return reflect.Uint 1144 case kind >= reflect.Float32 && kind <= reflect.Float64: 1145 return reflect.Float32 1146 default: 1147 return kind 1148 } 1149} 1150