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