[
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2013 Mitchell Hashimoto, William Kennedy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# mapstructure\n\nmapstructure is a Go library for decoding generic map values to structures\nand vice versa, while providing helpful error handling.\n\nThis library is most useful when decoding values from some data stream (JSON,\nGob, etc.) where you don't _quite_ know the structure of the underlying data\nuntil you read a part of it. You can therefore read a `map[string]interface{}`\nand use this library to decode it into the proper underlying native Go\nstructure.\n\n## Installation\n\nStandard `go get`:\n\n```\n$ go get github.com/goinggo/mapstructure\n```\n\n## Usage & Example\n\nFor usage and examples see the [Godoc](http://godoc.org/github.com/mitchellh/mapstructure).\n\nThe `Decode`, `DecodePath` and `DecodeSlicePath` functions have examples associated with it there.\n\n## But Why?!\n\nGo offers fantastic standard libraries for decoding formats such as JSON.\nThe standard method is to have a struct pre-created, and populate that struct\nfrom the bytes of the encoded format. This is great, but the problem is if\nyou have configuration or an encoding that changes slightly depending on\nspecific fields. For example, consider this JSON:\n\n```json\n{\n  \"type\": \"person\",\n  \"name\": \"Mitchell\"\n}\n```\n\nPerhaps we can't populate a specific structure without first reading\nthe \"type\" field from the JSON. We could always do two passes over the\ndecoding of the JSON (reading the \"type\" first, and the rest later).\nHowever, it is much simpler to just decode this into a `map[string]interface{}`\nstructure, read the \"type\" key, then use something like this library\nto decode it into the proper structure.\n\n## DecodePath\n\nSometimes you have a large and complex JSON document where you only need to decode\na small part.\n\n```\n{\n\t\"userContext\": {\n\t\t\"conversationCredentials\": {\n\t            \"sessionToken\": \"06142010_1:75bf6a413327dd71ebe8f3f30c5a4210a9b11e93c028d6e11abfca7ff\"\n\t    },\n\t    \"valid\": true,\n\t    \"isPasswordExpired\": false,\n\t    \"cobrandId\": 10000004,\n\t    \"channelId\": -1,\n\t    \"locale\": \"en_US\",\n\t    \"tncVersion\": 2,\n\t    \"applicationId\": \"17CBE222A42161A3FF450E47CF4C1A00\",\n\t    \"cobrandConversationCredentials\": {\n\t        \"sessionToken\": \"06142010_1:b8d011fefbab8bf1753391b074ffedf9578612d676ed2b7f073b5785b\"\n\t    },\n\t     \"preferenceInfo\": {\n\t         \"currencyCode\": \"USD\",\n\t         \"timeZone\": \"PST\",\n\t         \"dateFormat\": \"MM/dd/yyyy\",\n\t         \"currencyNotationType\": {\n\t             \"currencyNotationType\": \"SYMBOL\"\n\t         },\n\t         \"numberFormat\": {\n\t             \"decimalSeparator\": \".\",\n\t             \"groupingSeparator\": \",\",\n\t             \"groupPattern\": \"###,##0.##\"\n\t         }\n\t     }\n\t },\n\t \"lastLoginTime\": 1375686841,\n\t \"loginCount\": 299,\n\t \"passwordRecovered\": false,\n\t \"emailAddress\": \"johndoe@email.com\",\n\t \"loginName\": \"sptest1\",\n\t \"userId\": 10483860,\n\t \"userType\":\n\t     {\n\t     \"userTypeId\": 1,\n\t     \"userTypeName\": \"normal_user\"\n\t     }\n}\n```\n\nIt is nice to be able to define and pull the documents and fields you need without\nhaving to map the entire JSON structure.\n\n```\ntype UserType struct {\n\tUserTypeId   int\n\tUserTypeName string\n}\n\ntype NumberFormat struct {\n\t\tDecimalSeparator  string `jpath:\"userContext.preferenceInfo.numberFormat.decimalSeparator\"`\n\t\tGroupingSeparator string `jpath:\"userContext.preferenceInfo.numberFormat.groupingSeparator\"`\n\t\tGroupPattern      string `jpath:\"userContext.preferenceInfo.numberFormat.groupPattern\"`\n\t}\n\t\ntype User struct {\n\t\tSession   string   `jpath:\"userContext.cobrandConversationCredentials.sessionToken\"`\n\t\tCobrandId int      `jpath:\"userContext.cobrandId\"`\n\t\tUserType  UserType `jpath:\"userType\"`\n\t\tLoginName string   `jpath:\"loginName\"`\n\t\tNumberFormat       // This can also be a pointer to the struct (*NumberFormat)\n}\n\ndocScript := []byte(document)\nvar docMap map[string]interface{}\njson.Unmarshal(docScript, &docMap)\n\nvar user User\nmapstructure.DecodePath(docMap, &user)\n```\n\n## DecodeSlicePath\n\nSometimes you have a slice of documents that you need to decode into a slice of structures\n\n```\n[\n\t{\"name\":\"bill\"},\n\t{\"name\":\"lisa\"}\n]\n```\n\nJust Unmarshal your document into a slice of maps and decode the slice\n\n```\ntype NameDoc struct {\n\tName string `jpath:\"name\"`\n}\n\nsliceScript := []byte(document)\nvar sliceMap []map[string]interface{}\njson.Unmarshal(sliceScript, &sliceMap)\n\nvar myslice []NameDoc\nerr := DecodeSlicePath(sliceMap, &myslice)\n\nvar myslice []*NameDoc\nerr := DecodeSlicePath(sliceMap, &myslice)\n```\n\n## Decode Structs With Embedded Slices\n\nSometimes you have a document with arrays\n\n```\n{\n\t\"cobrandId\": 10010352,\n\t\"channelId\": -1,\n\t\"locale\": \"en_US\",\n\t\"tncVersion\": 2,\n\t\"people\": [\n\t\t{\n\t\t\t\"name\": \"jack\",\n\t\t\t\"age\": {\n\t\t\t\"birth\":10,\n\t\t\t\"year\":2000,\n\t\t\t\"animals\": [\n\t\t\t\t{\n\t\t\t\t\"barks\":\"yes\",\n\t\t\t\t\"tail\":\"yes\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\"barks\":\"no\",\n\t\t\t\t\"tail\":\"yes\"\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t\t},\n\t\t{\n\t\t\t\"name\": \"jill\",\n\t\t\t\"age\": {\n\t\t\t\t\"birth\":11,\n\t\t\t\t\"year\":2001\n\t\t\t}\n\t\t}\n\t]\n}\n```\n\nYou can decode within those arrays\n\n```\ntype Animal struct {\n\tBarks string `jpath:\"barks\"`\n}\n\ntype People struct {\n\tAge     int      `jpath:\"age.birth\"` // jpath is relative to the array\n\tAnimals []Animal `jpath:\"age.animals\"`\n}\n\ntype Items struct {\n\tCategories []string `jpath:\"categories\"`\n\tPeoples    []People `jpath:\"people\"` // Specify the location of the array\n}\n\ndocScript := []byte(document)\nvar docMap map[string]interface{}\njson.Unmarshal(docScript, &docMap)\n\nvar items Items\nDecodePath(docMap, &items)\n```"
  },
  {
    "path": "error.go",
    "content": "package mapstructure\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\n// Error implements the error interface and can represents multiple\n// errors that occur in the course of a single decode.\ntype Error struct {\n\tErrors []string\n}\n\nfunc (e *Error) Error() string {\n\tpoints := make([]string, len(e.Errors))\n\tfor i, err := range e.Errors {\n\t\tpoints[i] = fmt.Sprintf(\"* %s\", err)\n\t}\n\n\treturn fmt.Sprintf(\n\t\t\"%d error(s) decoding:\\n\\n%s\",\n\t\tlen(e.Errors), strings.Join(points, \"\\n\"))\n}\n\nfunc appendErrors(errors []string, err error) []string {\n\tswitch e := err.(type) {\n\tcase *Error:\n\t\treturn append(errors, e.Errors...)\n\tdefault:\n\t\treturn append(errors, e.Error())\n\t}\n}\n"
  },
  {
    "path": "mapstructure.go",
    "content": "// The mapstructure package exposes functionality to convert an\n// abitrary map[string]interface{} into a native Go structure.\n//\n// The Go structure can be arbitrarily complex, containing slices,\n// other structs, etc. and the decoder will properly decode nested\n// maps and so on into the proper structures in the native Go struct.\n// See the examples to see what the decoder is capable of.\npackage mapstructure\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n)\n\ntype DecodeHookFunc func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error)\n\n// DecoderConfig is the configuration that is used to create a new decoder\n// and allows customization of various aspects of decoding.\ntype DecoderConfig struct {\n\t// DecodeHook, if set, will be called before any decoding and any\n\t// type conversion (if WeaklyTypedInput is on). This lets you modify\n\t// the values before they're set down onto the resulting struct.\n\t//\n\t// If an error is returned, the entire decode will fail with that\n\t// error.\n\tDecodeHook DecodeHookFunc\n\n\t// If ErrorUnused is true, then it is an error for there to exist\n\t// keys in the original map that were unused in the decoding process\n\t// (extra keys).\n\tErrorUnused bool\n\n\t// If WeaklyTypedInput is true, the decoder will make the following\n\t// \"weak\" conversions:\n\t//\n\t//   - bools to string (true = \"1\", false = \"0\")\n\t//   - numbers to string (base 10)\n\t//   - bools to int/uint (true = 1, false = 0)\n\t//   - strings to int/uint (base implied by prefix)\n\t//   - int to bool (true if value != 0)\n\t//   - string to bool (accepts: 1, t, T, TRUE, true, True, 0, f, F,\n\t//     FALSE, false, False. Anything else is an error)\n\t//   - empty array = empty map and vice versa\n\t//\n\tWeaklyTypedInput bool\n\n\t// Metadata is the struct that will contain extra metadata about\n\t// the decoding. If this is nil, then no metadata will be tracked.\n\tMetadata *Metadata\n\n\t// Result is a pointer to the struct that will contain the decoded\n\t// value.\n\tResult interface{}\n\n\t// The tag name that mapstructure reads for field names. This\n\t// defaults to \"mapstructure\"\n\tTagName string\n}\n\n// A Decoder takes a raw interface value and turns it into structured\n// data, keeping track of rich error information along the way in case\n// anything goes wrong. Unlike the basic top-level Decode method, you can\n// more finely control how the Decoder behaves using the DecoderConfig\n// structure. The top-level Decode method is just a convenience that sets\n// up the most basic Decoder.\ntype Decoder struct {\n\tconfig *DecoderConfig\n}\n\n// Metadata contains information about decoding a structure that\n// is tedious or difficult to get otherwise.\ntype Metadata struct {\n\t// Keys are the keys of the structure which were successfully decoded\n\tKeys []string\n\n\t// Unused is a slice of keys that were found in the raw value but\n\t// weren't decoded since there was no matching field in the result interface\n\tUnused []string\n}\n\n// Decode takes a map and uses reflection to convert it into the\n// given Go native structure. val must be a pointer to a struct.\nfunc Decode(m interface{}, rawVal interface{}) error {\n\tconfig := &DecoderConfig{\n\t\tMetadata: nil,\n\t\tResult:   rawVal,\n\t}\n\n\tdecoder, err := NewDecoder(config)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn decoder.Decode(m)\n}\n\n// DecodePath takes a map and uses reflection to convert it into the\n// given Go native structure. Tags are used to specify the mapping\n// between fields in the map and structure\nfunc DecodePath(m map[string]interface{}, rawVal interface{}) error {\n\tconfig := &DecoderConfig{\n\t\tMetadata: nil,\n\t\tResult:   nil,\n\t}\n\n\tdecoder, err := NewPathDecoder(config)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t_, err = decoder.DecodePath(m, rawVal)\n\treturn err\n}\n\n// DecodeSlicePath decodes a slice of maps against a slice of structures that\n// contain specified tags\nfunc DecodeSlicePath(ms []map[string]interface{}, rawSlice interface{}) error {\n\treflectRawSlice := reflect.TypeOf(rawSlice)\n\trawKind := reflectRawSlice.Kind()\n\trawElement := reflectRawSlice.Elem()\n\n\tif (rawKind == reflect.Ptr && rawElement.Kind() != reflect.Slice) ||\n\t\t(rawKind != reflect.Ptr && rawKind != reflect.Slice) {\n\t\treturn fmt.Errorf(\"Incompatible Value, Looking For Slice : %v : %v\", rawKind, rawElement.Kind())\n\t}\n\n\tconfig := &DecoderConfig{\n\t\tMetadata: nil,\n\t\tResult:   nil,\n\t}\n\n\tdecoder, err := NewPathDecoder(config)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Create a slice large enough to decode all the values\n\tvalSlice := reflect.MakeSlice(rawElement, len(ms), len(ms))\n\n\t// Iterate over the maps and decode each one\n\tfor index, m := range ms {\n\t\tsliceElementType := rawElement.Elem()\n\t\tif sliceElementType.Kind() != reflect.Ptr {\n\t\t\t// A slice of objects\n\t\t\tobj := reflect.New(rawElement.Elem())\n\t\t\tdecoder.DecodePath(m, reflect.Indirect(obj))\n\t\t\tindexVal := valSlice.Index(index)\n\t\t\tindexVal.Set(reflect.Indirect(obj))\n\t\t} else {\n\t\t\t// A slice of pointers\n\t\t\tobj := reflect.New(rawElement.Elem().Elem())\n\t\t\tdecoder.DecodePath(m, reflect.Indirect(obj))\n\t\t\tindexVal := valSlice.Index(index)\n\t\t\tindexVal.Set(obj)\n\t\t}\n\t}\n\n\t// Set the new slice\n\treflect.ValueOf(rawSlice).Elem().Set(valSlice)\n\treturn nil\n}\n\n// NewDecoder returns a new decoder for the given configuration. Once\n// a decoder has been returned, the same configuration must not be used\n// again.\nfunc NewDecoder(config *DecoderConfig) (*Decoder, error) {\n\tval := reflect.ValueOf(config.Result)\n\tif val.Kind() != reflect.Ptr {\n\t\treturn nil, errors.New(\"result must be a pointer\")\n\t}\n\n\tval = val.Elem()\n\tif !val.CanAddr() {\n\t\treturn nil, errors.New(\"result must be addressable (a pointer)\")\n\t}\n\n\tif config.Metadata != nil {\n\t\tif config.Metadata.Keys == nil {\n\t\t\tconfig.Metadata.Keys = make([]string, 0)\n\t\t}\n\n\t\tif config.Metadata.Unused == nil {\n\t\t\tconfig.Metadata.Unused = make([]string, 0)\n\t\t}\n\t}\n\n\tif config.TagName == \"\" {\n\t\tconfig.TagName = \"mapstructure\"\n\t}\n\n\tresult := &Decoder{\n\t\tconfig: config,\n\t}\n\n\treturn result, nil\n}\n\n// NewPathDecoder returns a new decoder for the given configuration.\n// This is used to decode path specific structures\nfunc NewPathDecoder(config *DecoderConfig) (*Decoder, error) {\n\tif config.Metadata != nil {\n\t\tif config.Metadata.Keys == nil {\n\t\t\tconfig.Metadata.Keys = make([]string, 0)\n\t\t}\n\n\t\tif config.Metadata.Unused == nil {\n\t\t\tconfig.Metadata.Unused = make([]string, 0)\n\t\t}\n\t}\n\n\tif config.TagName == \"\" {\n\t\tconfig.TagName = \"mapstructure\"\n\t}\n\n\tresult := &Decoder{\n\t\tconfig: config,\n\t}\n\n\treturn result, nil\n}\n\n// Decode decodes the given raw interface to the target pointer specified\n// by the configuration.\nfunc (d *Decoder) Decode(raw interface{}) error {\n\treturn d.decode(\"\", raw, reflect.ValueOf(d.config.Result).Elem())\n}\n\n// DecodePath decodes the raw interface against the map based on the\n// specified tags\nfunc (d *Decoder) DecodePath(m map[string]interface{}, rawVal interface{}) (bool, error) {\n\tdecoded := false\n\n\tvar val reflect.Value\n\treflectRawValue := reflect.ValueOf(rawVal)\n\tkind := reflectRawValue.Kind()\n\n\t// Looking for structs and pointers to structs\n\tswitch kind {\n\tcase reflect.Ptr:\n\t\tval = reflectRawValue.Elem()\n\t\tif val.Kind() != reflect.Struct {\n\t\t\treturn decoded, fmt.Errorf(\"Incompatible Type : %v : Looking For Struct\", kind)\n\t\t}\n\tcase reflect.Struct:\n\t\tvar ok bool\n\t\tval, ok = rawVal.(reflect.Value)\n\t\tif ok == false {\n\t\t\treturn decoded, fmt.Errorf(\"Incompatible Type : %v : Looking For reflect.Value\", kind)\n\t\t}\n\tdefault:\n\t\treturn decoded, fmt.Errorf(\"Incompatible Type : %v\", kind)\n\t}\n\n\t// Iterate over the fields in the struct\n\tfor i := 0; i < val.NumField(); i++ {\n\t\tvalueField := val.Field(i)\n\t\ttypeField := val.Type().Field(i)\n\t\ttag := typeField.Tag\n\t\ttagValue := tag.Get(\"jpath\")\n\n\t\t// Is this a field without a tag\n\t\tif tagValue == \"\" {\n\t\t\tif valueField.Kind() == reflect.Struct {\n\t\t\t\t// We have a struct that may have indivdual tags. Process separately\n\t\t\t\td.DecodePath(m, valueField)\n\t\t\t\tcontinue\n\t\t\t} else if valueField.Kind() == reflect.Ptr && reflect.TypeOf(valueField).Kind() == reflect.Struct {\n\t\t\t\t// We have a pointer to a struct\n\t\t\t\tif valueField.IsNil() {\n\t\t\t\t\t// Create the object since it doesn't exist\n\t\t\t\t\tvalueField.Set(reflect.New(valueField.Type().Elem()))\n\t\t\t\t\tdecoded, _ = d.DecodePath(m, valueField.Elem())\n\t\t\t\t\tif decoded == false {\n\t\t\t\t\t\t// If nothing was decoded for this object return the pointer to nil\n\t\t\t\t\t\tvalueField.Set(reflect.NewAt(valueField.Type().Elem(), nil))\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\td.DecodePath(m, valueField.Elem())\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// Use mapstructure to populate the fields\n\t\tkeys := strings.Split(tagValue, \".\")\n\t\tdata := d.findData(m, keys)\n\t\tif data != nil {\n\t\t\tif valueField.Kind() == reflect.Slice {\n\t\t\t\t// Ignore a slice of maps - This sucks but not sure how to check\n\t\t\t\tif strings.Contains(valueField.Type().String(), \"map[\") {\n\t\t\t\t\tgoto normal_decode\n\t\t\t\t}\n\n\t\t\t\t// We have a slice\n\t\t\t\tmapSlice := data.([]interface{})\n\t\t\t\tif len(mapSlice) > 0 {\n\t\t\t\t\t// Test if this is a slice of more maps\n\t\t\t\t\t_, ok := mapSlice[0].(map[string]interface{})\n\t\t\t\t\tif ok == false {\n\t\t\t\t\t\tgoto normal_decode\n\t\t\t\t\t}\n\n\t\t\t\t\t// Extract the maps out and run it through DecodeSlicePath\n\t\t\t\t\tms := make([]map[string]interface{}, len(mapSlice))\n\t\t\t\t\tfor index, m2 := range mapSlice {\n\t\t\t\t\t\tms[index] = m2.(map[string]interface{})\n\t\t\t\t\t}\n\n\t\t\t\t\tDecodeSlicePath(ms, valueField.Addr().Interface())\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\tnormal_decode:\n\t\t\tdecoded = true\n\t\t\terr := d.decode(\"\", data, valueField)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t}\n\n\treturn decoded, nil\n}\n\n// Decodes an unknown data type into a specific reflection value.\nfunc (d *Decoder) decode(name string, data interface{}, val reflect.Value) error {\n\tif data == nil {\n\t\t// If the data is nil, then we don't set anything.\n\t\treturn nil\n\t}\n\n\tdataVal := reflect.ValueOf(data)\n\tif !dataVal.IsValid() {\n\t\t// If the data value is invalid, then we just set the value\n\t\t// to be the zero value.\n\t\tval.Set(reflect.Zero(val.Type()))\n\t\treturn nil\n\t}\n\n\tif d.config.DecodeHook != nil {\n\t\t// We have a DecodeHook, so let's pre-process the data.\n\t\tvar err error\n\t\tdata, err = d.config.DecodeHook(d.getKind(dataVal), d.getKind(val), data)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tvar err error\n\tdataKind := d.getKind(val)\n\tswitch dataKind {\n\tcase reflect.Bool:\n\t\terr = d.decodeBool(name, data, val)\n\tcase reflect.Interface:\n\t\terr = d.decodeBasic(name, data, val)\n\tcase reflect.String:\n\t\terr = d.decodeString(name, data, val)\n\tcase reflect.Int:\n\t\terr = d.decodeInt(name, data, val)\n\tcase reflect.Uint:\n\t\terr = d.decodeUint(name, data, val)\n\tcase reflect.Float32:\n\t\terr = d.decodeFloat(name, data, val)\n\tcase reflect.Struct:\n\t\terr = d.decodeStruct(name, data, val)\n\tcase reflect.Map:\n\t\terr = d.decodeMap(name, data, val)\n\tcase reflect.Slice:\n\t\terr = d.decodeSlice(name, data, val)\n\tdefault:\n\t\t// If we reached this point then we weren't able to decode it\n\t\treturn fmt.Errorf(\"%s: unsupported type: %s\", name, dataKind)\n\t}\n\n\t// If we reached here, then we successfully decoded SOMETHING, so\n\t// mark the key as used if we're tracking metadata.\n\tif d.config.Metadata != nil && name != \"\" {\n\t\td.config.Metadata.Keys = append(d.config.Metadata.Keys, name)\n\t}\n\n\treturn err\n}\n\n// findData locates the data by walking the keys down the map\nfunc (d *Decoder) findData(m map[string]interface{}, keys []string) interface{} {\n\tif len(keys) == 1 {\n\t\tif value, ok := m[keys[0]]; ok == true {\n\t\t\treturn value\n\t\t}\n\t\treturn nil\n\t}\n\n\tif value, ok := m[keys[0]]; ok == true {\n\t\tif m, ok := value.(map[string]interface{}); ok == true {\n\t\t\treturn d.findData(m, keys[1:])\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (d *Decoder) getKind(val reflect.Value) reflect.Kind {\n\tkind := val.Kind()\n\n\tswitch {\n\tcase kind >= reflect.Int && kind <= reflect.Int64:\n\t\treturn reflect.Int\n\tcase kind >= reflect.Uint && kind <= reflect.Uint64:\n\t\treturn reflect.Uint\n\tcase kind >= reflect.Float32 && kind <= reflect.Float64:\n\t\treturn reflect.Float32\n\tdefault:\n\t\treturn kind\n\t}\n}\n\n// This decodes a basic type (bool, int, string, etc.) and sets the\n// value to \"data\" of that type.\nfunc (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error {\n\tdataVal := reflect.ValueOf(data)\n\tdataValType := dataVal.Type()\n\tif !dataValType.AssignableTo(val.Type()) {\n\t\treturn fmt.Errorf(\n\t\t\t\"'%s' expected type '%s', got '%s'\",\n\t\t\tname, val.Type(), dataValType)\n\t}\n\n\tval.Set(dataVal)\n\treturn nil\n}\n\nfunc (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) error {\n\tdataVal := reflect.ValueOf(data)\n\tdataKind := d.getKind(dataVal)\n\n\tswitch {\n\tcase dataKind == reflect.String:\n\t\tval.SetString(dataVal.String())\n\tcase dataKind == reflect.Bool && d.config.WeaklyTypedInput:\n\t\tif dataVal.Bool() {\n\t\t\tval.SetString(\"1\")\n\t\t} else {\n\t\t\tval.SetString(\"0\")\n\t\t}\n\tcase dataKind == reflect.Int && d.config.WeaklyTypedInput:\n\t\tval.SetString(strconv.FormatInt(dataVal.Int(), 10))\n\tcase dataKind == reflect.Uint && d.config.WeaklyTypedInput:\n\t\tval.SetString(strconv.FormatUint(dataVal.Uint(), 10))\n\tcase dataKind == reflect.Float32 && d.config.WeaklyTypedInput:\n\t\tval.SetString(strconv.FormatFloat(dataVal.Float(), 'f', -1, 64))\n\tdefault:\n\t\treturn fmt.Errorf(\n\t\t\t\"'%s' expected type '%s', got unconvertible type '%s'\",\n\t\t\tname, val.Type(), dataVal.Type())\n\t}\n\n\treturn nil\n}\n\nfunc (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) error {\n\tdataVal := reflect.ValueOf(data)\n\tdataKind := d.getKind(dataVal)\n\n\tswitch {\n\tcase dataKind == reflect.Int:\n\t\tval.SetInt(dataVal.Int())\n\tcase dataKind == reflect.Uint:\n\t\tval.SetInt(int64(dataVal.Uint()))\n\tcase dataKind == reflect.Float32:\n\t\tval.SetInt(int64(dataVal.Float()))\n\tcase dataKind == reflect.Bool && d.config.WeaklyTypedInput:\n\t\tif dataVal.Bool() {\n\t\t\tval.SetInt(1)\n\t\t} else {\n\t\t\tval.SetInt(0)\n\t\t}\n\tcase dataKind == reflect.String && d.config.WeaklyTypedInput:\n\t\ti, err := strconv.ParseInt(dataVal.String(), 0, val.Type().Bits())\n\t\tif err == nil {\n\t\t\tval.SetInt(i)\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"cannot parse '%s' as int: %s\", name, err)\n\t\t}\n\tdefault:\n\t\treturn fmt.Errorf(\n\t\t\t\"'%s' expected type '%s', got unconvertible type '%s'\",\n\t\t\tname, val.Type(), dataVal.Type())\n\t}\n\n\treturn nil\n}\n\nfunc (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) error {\n\tdataVal := reflect.ValueOf(data)\n\tdataKind := d.getKind(dataVal)\n\n\tswitch {\n\tcase dataKind == reflect.Int:\n\t\tval.SetUint(uint64(dataVal.Int()))\n\tcase dataKind == reflect.Uint:\n\t\tval.SetUint(dataVal.Uint())\n\tcase dataKind == reflect.Float32:\n\t\tval.SetUint(uint64(dataVal.Float()))\n\tcase dataKind == reflect.Bool && d.config.WeaklyTypedInput:\n\t\tif dataVal.Bool() {\n\t\t\tval.SetUint(1)\n\t\t} else {\n\t\t\tval.SetUint(0)\n\t\t}\n\tcase dataKind == reflect.String && d.config.WeaklyTypedInput:\n\t\ti, err := strconv.ParseUint(dataVal.String(), 0, val.Type().Bits())\n\t\tif err == nil {\n\t\t\tval.SetUint(i)\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"cannot parse '%s' as uint: %s\", name, err)\n\t\t}\n\tdefault:\n\t\treturn fmt.Errorf(\n\t\t\t\"'%s' expected type '%s', got unconvertible type '%s'\",\n\t\t\tname, val.Type(), dataVal.Type())\n\t}\n\n\treturn nil\n}\n\nfunc (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) error {\n\tdataVal := reflect.ValueOf(data)\n\tdataKind := d.getKind(dataVal)\n\n\tswitch {\n\tcase dataKind == reflect.Bool:\n\t\tval.SetBool(dataVal.Bool())\n\tcase dataKind == reflect.Int && d.config.WeaklyTypedInput:\n\t\tval.SetBool(dataVal.Int() != 0)\n\tcase dataKind == reflect.Uint && d.config.WeaklyTypedInput:\n\t\tval.SetBool(dataVal.Uint() != 0)\n\tcase dataKind == reflect.Float32 && d.config.WeaklyTypedInput:\n\t\tval.SetBool(dataVal.Float() != 0)\n\tcase dataKind == reflect.String && d.config.WeaklyTypedInput:\n\t\tb, err := strconv.ParseBool(dataVal.String())\n\t\tif err == nil {\n\t\t\tval.SetBool(b)\n\t\t} else if dataVal.String() == \"\" {\n\t\t\tval.SetBool(false)\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"cannot parse '%s' as bool: %s\", name, err)\n\t\t}\n\tdefault:\n\t\treturn fmt.Errorf(\n\t\t\t\"'%s' expected type '%s', got unconvertible type '%s'\",\n\t\t\tname, val.Type(), dataVal.Type())\n\t}\n\n\treturn nil\n}\n\nfunc (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) error {\n\tdataVal := reflect.ValueOf(data)\n\tdataKind := d.getKind(dataVal)\n\n\tswitch {\n\tcase dataKind == reflect.Int:\n\t\tval.SetFloat(float64(dataVal.Int()))\n\tcase dataKind == reflect.Uint:\n\t\tval.SetFloat(float64(dataVal.Uint()))\n\tcase dataKind == reflect.Float32:\n\t\tval.SetFloat(float64(dataVal.Float()))\n\tcase dataKind == reflect.Bool && d.config.WeaklyTypedInput:\n\t\tif dataVal.Bool() {\n\t\t\tval.SetFloat(1)\n\t\t} else {\n\t\t\tval.SetFloat(0)\n\t\t}\n\tcase dataKind == reflect.String && d.config.WeaklyTypedInput:\n\t\tf, err := strconv.ParseFloat(dataVal.String(), val.Type().Bits())\n\t\tif err == nil {\n\t\t\tval.SetFloat(f)\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"cannot parse '%s' as float: %s\", name, err)\n\t\t}\n\tdefault:\n\t\treturn fmt.Errorf(\n\t\t\t\"'%s' expected type '%s', got unconvertible type '%s'\",\n\t\t\tname, val.Type(), dataVal.Type())\n\t}\n\n\treturn nil\n}\n\nfunc (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) error {\n\tvalType := val.Type()\n\tvalKeyType := valType.Key()\n\tvalElemType := valType.Elem()\n\n\t// Make a new map to hold our result\n\tmapType := reflect.MapOf(valKeyType, valElemType)\n\tvalMap := reflect.MakeMap(mapType)\n\n\t// Check input type\n\tdataVal := reflect.Indirect(reflect.ValueOf(data))\n\tif dataVal.Kind() != reflect.Map {\n\t\t// Accept empty array/slice instead of an empty map in weakly typed mode\n\t\tif d.config.WeaklyTypedInput &&\n\t\t\t(dataVal.Kind() == reflect.Slice || dataVal.Kind() == reflect.Array) &&\n\t\t\tdataVal.Len() == 0 {\n\t\t\tval.Set(valMap)\n\t\t\treturn nil\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"'%s' expected a map, got '%s'\", name, dataVal.Kind())\n\t\t}\n\t}\n\n\t// Accumulate errors\n\terrors := make([]string, 0)\n\n\tfor _, k := range dataVal.MapKeys() {\n\t\tfieldName := fmt.Sprintf(\"%s[%s]\", name, k)\n\n\t\t// First decode the key into the proper type\n\t\tcurrentKey := reflect.Indirect(reflect.New(valKeyType))\n\t\tif err := d.decode(fieldName, k.Interface(), currentKey); err != nil {\n\t\t\terrors = appendErrors(errors, err)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Next decode the data into the proper type\n\t\tv := dataVal.MapIndex(k).Interface()\n\t\tcurrentVal := reflect.Indirect(reflect.New(valElemType))\n\t\tif err := d.decode(fieldName, v, currentVal); err != nil {\n\t\t\terrors = appendErrors(errors, err)\n\t\t\tcontinue\n\t\t}\n\n\t\tvalMap.SetMapIndex(currentKey, currentVal)\n\t}\n\n\t// Set the built up map to the value\n\tval.Set(valMap)\n\n\t// If we had errors, return those\n\tif len(errors) > 0 {\n\t\treturn &Error{errors}\n\t}\n\n\treturn nil\n}\n\nfunc (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error {\n\tdataVal := reflect.Indirect(reflect.ValueOf(data))\n\tdataValKind := dataVal.Kind()\n\tvalType := val.Type()\n\tvalElemType := valType.Elem()\n\n\t// Make a new slice to hold our result, same size as the original data.\n\tsliceType := reflect.SliceOf(valElemType)\n\tvalSlice := reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len())\n\n\t// Check input type\n\tif dataValKind != reflect.Array && dataValKind != reflect.Slice {\n\t\t// Accept empty map instead of array/slice in weakly typed mode\n\t\tif d.config.WeaklyTypedInput && dataVal.Kind() == reflect.Map && dataVal.Len() == 0 {\n\t\t\tval.Set(valSlice)\n\t\t\treturn nil\n\t\t} else {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"'%s': source data must be an array or slice, got %s\", name, dataValKind)\n\t\t}\n\t}\n\n\t// Accumulate any errors\n\terrors := make([]string, 0)\n\n\tfor i := 0; i < dataVal.Len(); i++ {\n\t\tcurrentData := dataVal.Index(i).Interface()\n\t\tcurrentField := valSlice.Index(i)\n\n\t\tfieldName := fmt.Sprintf(\"%s[%d]\", name, i)\n\t\tif err := d.decode(fieldName, currentData, currentField); err != nil {\n\t\t\terrors = appendErrors(errors, err)\n\t\t}\n\t}\n\n\t// Finally, set the value to the slice we built up\n\tval.Set(valSlice)\n\n\t// If there were errors, we return those\n\tif len(errors) > 0 {\n\t\treturn &Error{errors}\n\t}\n\n\treturn nil\n}\n\nfunc (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) error {\n\tdataVal := reflect.Indirect(reflect.ValueOf(data))\n\tdataValKind := dataVal.Kind()\n\tif dataValKind != reflect.Map {\n\t\treturn fmt.Errorf(\"'%s' expected a map, got '%s'\", name, dataValKind)\n\t}\n\n\tdataValType := dataVal.Type()\n\tif kind := dataValType.Key().Kind(); kind != reflect.String && kind != reflect.Interface {\n\t\treturn fmt.Errorf(\n\t\t\t\"'%s' needs a map with string keys, has '%s' keys\",\n\t\t\tname, dataValType.Key().Kind())\n\t}\n\n\tdataValKeys := make(map[reflect.Value]struct{})\n\tdataValKeysUnused := make(map[interface{}]struct{})\n\tfor _, dataValKey := range dataVal.MapKeys() {\n\t\tdataValKeys[dataValKey] = struct{}{}\n\t\tdataValKeysUnused[dataValKey.Interface()] = struct{}{}\n\t}\n\n\terrors := make([]string, 0)\n\n\t// This slice will keep track of all the structs we'll be decoding.\n\t// There can be more than one struct if there are embedded structs\n\t// that are squashed.\n\tstructs := make([]reflect.Value, 1, 5)\n\tstructs[0] = val\n\n\t// Compile the list of all the fields that we're going to be decoding\n\t// from all the structs.\n\tfields := make(map[*reflect.StructField]reflect.Value)\n\tfor len(structs) > 0 {\n\t\tstructVal := structs[0]\n\t\tstructs = structs[1:]\n\n\t\tstructType := structVal.Type()\n\t\tfor i := 0; i < structType.NumField(); i++ {\n\t\t\tfieldType := structType.Field(i)\n\n\t\t\tif fieldType.Anonymous {\n\t\t\t\tfieldKind := fieldType.Type.Kind()\n\t\t\t\tif fieldKind != reflect.Struct {\n\t\t\t\t\terrors = appendErrors(errors,\n\t\t\t\t\t\tfmt.Errorf(\"%s: unsupported type: %s\", fieldType.Name, fieldKind))\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// We have an embedded field. We \"squash\" the fields down\n\t\t\t\t// if specified in the tag.\n\t\t\t\tsquash := false\n\t\t\t\ttagParts := strings.Split(fieldType.Tag.Get(d.config.TagName), \",\")\n\t\t\t\tfor _, tag := range tagParts[1:] {\n\t\t\t\t\tif tag == \"squash\" {\n\t\t\t\t\t\tsquash = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif squash {\n\t\t\t\t\tstructs = append(structs, val.FieldByName(fieldType.Name))\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Normal struct field, store it away\n\t\t\tfields[&fieldType] = structVal.Field(i)\n\t\t}\n\t}\n\n\tfor fieldType, field := range fields {\n\t\tfieldName := fieldType.Name\n\n\t\ttagValue := fieldType.Tag.Get(d.config.TagName)\n\t\ttagValue = strings.SplitN(tagValue, \",\", 2)[0]\n\t\tif tagValue != \"\" {\n\t\t\tfieldName = tagValue\n\t\t}\n\n\t\trawMapKey := reflect.ValueOf(fieldName)\n\t\trawMapVal := dataVal.MapIndex(rawMapKey)\n\t\tif !rawMapVal.IsValid() {\n\t\t\t// Do a slower search by iterating over each key and\n\t\t\t// doing case-insensitive search.\n\t\t\tfor dataValKey, _ := range dataValKeys {\n\t\t\t\tmK, ok := dataValKey.Interface().(string)\n\t\t\t\tif !ok {\n\t\t\t\t\t// Not a string key\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif strings.EqualFold(mK, fieldName) {\n\t\t\t\t\trawMapKey = dataValKey\n\t\t\t\t\trawMapVal = dataVal.MapIndex(dataValKey)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif !rawMapVal.IsValid() {\n\t\t\t\t// There was no matching key in the map for the value in\n\t\t\t\t// the struct. Just ignore.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// Delete the key we're using from the unused map so we stop tracking\n\t\tdelete(dataValKeysUnused, rawMapKey.Interface())\n\n\t\tif !field.IsValid() {\n\t\t\t// This should never happen\n\t\t\tpanic(\"field is not valid\")\n\t\t}\n\n\t\t// If we can't set the field, then it is unexported or something,\n\t\t// and we just continue onwards.\n\t\tif !field.CanSet() {\n\t\t\tcontinue\n\t\t}\n\n\t\t// If the name is empty string, then we're at the root, and we\n\t\t// don't dot-join the fields.\n\t\tif name != \"\" {\n\t\t\tfieldName = fmt.Sprintf(\"%s.%s\", name, fieldName)\n\t\t}\n\n\t\tif err := d.decode(fieldName, rawMapVal.Interface(), field); err != nil {\n\t\t\terrors = appendErrors(errors, err)\n\t\t}\n\t}\n\n\tif d.config.ErrorUnused && len(dataValKeysUnused) > 0 {\n\t\tkeys := make([]string, 0, len(dataValKeysUnused))\n\t\tfor rawKey, _ := range dataValKeysUnused {\n\t\t\tkeys = append(keys, rawKey.(string))\n\t\t}\n\t\tsort.Strings(keys)\n\n\t\terr := fmt.Errorf(\"'%s' has invalid keys: %s\", name, strings.Join(keys, \", \"))\n\t\terrors = appendErrors(errors, err)\n\t}\n\n\tif len(errors) > 0 {\n\t\treturn &Error{errors}\n\t}\n\n\t// Add the unused keys to the list of unused keys if we're tracking metadata\n\tif d.config.Metadata != nil {\n\t\tfor rawKey, _ := range dataValKeysUnused {\n\t\t\tkey := rawKey.(string)\n\t\t\tif name != \"\" {\n\t\t\t\tkey = fmt.Sprintf(\"%s.%s\", name, key)\n\t\t\t}\n\n\t\t\td.config.Metadata.Unused = append(d.config.Metadata.Unused, key)\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "mapstructure_benchmark_test.go",
    "content": "package mapstructure\n\nimport (\n\t\"testing\"\n)\n\nfunc Benchmark_Decode(b *testing.B) {\n\ttype Person struct {\n\t\tName   string\n\t\tAge    int\n\t\tEmails []string\n\t\tExtra  map[string]string\n\t}\n\n\tinput := map[string]interface{}{\n\t\t\"name\":   \"Mitchell\",\n\t\t\"age\":    91,\n\t\t\"emails\": []string{\"one\", \"two\", \"three\"},\n\t\t\"extra\": map[string]string{\n\t\t\t\"twitter\": \"mitchellh\",\n\t\t},\n\t}\n\n\tvar result Person\n\tfor i := 0; i < b.N; i++ {\n\t\tDecode(input, &result)\n\t}\n}\n\nfunc Benchmark_DecodeBasic(b *testing.B) {\n\tinput := map[string]interface{}{\n\t\t\"vstring\": \"foo\",\n\t\t\"vint\":    42,\n\t\t\"Vuint\":   42,\n\t\t\"vbool\":   true,\n\t\t\"Vfloat\":  42.42,\n\t\t\"vsilent\": true,\n\t\t\"vdata\":   42,\n\t}\n\n\tvar result Basic\n\tfor i := 0; i < b.N; i++ {\n\t\tDecode(input, &result)\n\t}\n}\n\nfunc Benchmark_DecodeEmbedded(b *testing.B) {\n\tinput := map[string]interface{}{\n\t\t\"vstring\": \"foo\",\n\t\t\"Basic\": map[string]interface{}{\n\t\t\t\"vstring\": \"innerfoo\",\n\t\t},\n\t\t\"vunique\": \"bar\",\n\t}\n\n\tvar result Embedded\n\tfor i := 0; i < b.N; i++ {\n\t\tDecode(input, &result)\n\t}\n}\n\nfunc Benchmark_DecodeTypeConversion(b *testing.B) {\n\tinput := map[string]interface{}{\n\t\t\"IntToFloat\":    42,\n\t\t\"IntToUint\":     42,\n\t\t\"IntToBool\":     1,\n\t\t\"IntToString\":   42,\n\t\t\"UintToInt\":     42,\n\t\t\"UintToFloat\":   42,\n\t\t\"UintToBool\":    42,\n\t\t\"UintToString\":  42,\n\t\t\"BoolToInt\":     true,\n\t\t\"BoolToUint\":    true,\n\t\t\"BoolToFloat\":   true,\n\t\t\"BoolToString\":  true,\n\t\t\"FloatToInt\":    42.42,\n\t\t\"FloatToUint\":   42.42,\n\t\t\"FloatToBool\":   42.42,\n\t\t\"FloatToString\": 42.42,\n\t\t\"StringToInt\":   \"42\",\n\t\t\"StringToUint\":  \"42\",\n\t\t\"StringToBool\":  \"1\",\n\t\t\"StringToFloat\": \"42.42\",\n\t\t\"SliceToMap\":    []interface{}{},\n\t\t\"MapToSlice\":    map[string]interface{}{},\n\t}\n\n\tvar resultStrict TypeConversionResult\n\tfor i := 0; i < b.N; i++ {\n\t\tDecode(input, &resultStrict)\n\t}\n}\n\nfunc Benchmark_DecodeMap(b *testing.B) {\n\tinput := map[string]interface{}{\n\t\t\"vfoo\": \"foo\",\n\t\t\"vother\": map[interface{}]interface{}{\n\t\t\t\"foo\": \"foo\",\n\t\t\t\"bar\": \"bar\",\n\t\t},\n\t}\n\n\tvar result Map\n\tfor i := 0; i < b.N; i++ {\n\t\tDecode(input, &result)\n\t}\n}\n\nfunc Benchmark_DecodeMapOfStruct(b *testing.B) {\n\tinput := map[string]interface{}{\n\t\t\"value\": map[string]interface{}{\n\t\t\t\"foo\": map[string]string{\"vstring\": \"one\"},\n\t\t\t\"bar\": map[string]string{\"vstring\": \"two\"},\n\t\t},\n\t}\n\n\tvar result MapOfStruct\n\tfor i := 0; i < b.N; i++ {\n\t\tDecode(input, &result)\n\t}\n}\n\nfunc Benchmark_DecodeSlice(b *testing.B) {\n\tinput := map[string]interface{}{\n\t\t\"vfoo\": \"foo\",\n\t\t\"vbar\": []string{\"foo\", \"bar\", \"baz\"},\n\t}\n\n\tvar result Slice\n\tfor i := 0; i < b.N; i++ {\n\t\tDecode(input, &result)\n\t}\n}\n\nfunc Benchmark_DecodeSliceOfStruct(b *testing.B) {\n\tinput := map[string]interface{}{\n\t\t\"value\": []map[string]interface{}{\n\t\t\t{\"vstring\": \"one\"},\n\t\t\t{\"vstring\": \"two\"},\n\t\t},\n\t}\n\n\tvar result SliceOfStruct\n\tfor i := 0; i < b.N; i++ {\n\t\tDecode(input, &result)\n\t}\n}\n\nfunc Benchmark_DecodeWeaklyTypedInput(b *testing.B) {\n\ttype Person struct {\n\t\tName   string\n\t\tAge    int\n\t\tEmails []string\n\t}\n\n\t// This input can come from anywhere, but typically comes from\n\t// something like decoding JSON, generated by a weakly typed language\n\t// such as PHP.\n\tinput := map[string]interface{}{\n\t\t\"name\":   123,                      // number => string\n\t\t\"age\":    \"42\",                     // string => number\n\t\t\"emails\": map[string]interface{}{}, // empty map => empty array\n\t}\n\n\tvar result Person\n\tconfig := &DecoderConfig{\n\t\tWeaklyTypedInput: true,\n\t\tResult:           &result,\n\t}\n\n\tdecoder, err := NewDecoder(config)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfor i := 0; i < b.N; i++ {\n\t\tdecoder.Decode(input)\n\t}\n}\n\nfunc Benchmark_DecodeMetadata(b *testing.B) {\n\ttype Person struct {\n\t\tName string\n\t\tAge  int\n\t}\n\n\tinput := map[string]interface{}{\n\t\t\"name\":  \"Mitchell\",\n\t\t\"age\":   91,\n\t\t\"email\": \"foo@bar.com\",\n\t}\n\n\tvar md Metadata\n\tvar result Person\n\tconfig := &DecoderConfig{\n\t\tMetadata: &md,\n\t\tResult:   &result,\n\t}\n\n\tdecoder, err := NewDecoder(config)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfor i := 0; i < b.N; i++ {\n\t\tdecoder.Decode(input)\n\t}\n}\n\nfunc Benchmark_DecodeMetadataEmbedded(b *testing.B) {\n\tinput := map[string]interface{}{\n\t\t\"vstring\": \"foo\",\n\t\t\"vunique\": \"bar\",\n\t}\n\n\tvar md Metadata\n\tvar result EmbeddedSquash\n\tconfig := &DecoderConfig{\n\t\tMetadata: &md,\n\t\tResult:   &result,\n\t}\n\n\tdecoder, err := NewDecoder(config)\n\tif err != nil {\n\t\tb.Fatalf(\"err: %s\", err)\n\t}\n\n\tfor i := 0; i < b.N; i++ {\n\t\tdecoder.Decode(input)\n\t}\n}\n\nfunc Benchmark_DecodeTagged(b *testing.B) {\n\tinput := map[string]interface{}{\n\t\t\"foo\": \"bar\",\n\t\t\"bar\": \"value\",\n\t}\n\n\tvar result Tagged\n\tfor i := 0; i < b.N; i++ {\n\t\tDecode(input, &result)\n\t}\n}\n"
  },
  {
    "path": "mapstructure_bugs_test.go",
    "content": "package mapstructure\n\nimport \"testing\"\n\n// GH-1\nfunc TestDecode_NilValue(t *testing.T) {\n\tinput := map[string]interface{}{\n\t\t\"vfoo\":   nil,\n\t\t\"vother\": nil,\n\t}\n\n\tvar result Map\n\terr := Decode(input, &result)\n\tif err != nil {\n\t\tt.Fatalf(\"should not error: %s\", err)\n\t}\n\n\tif result.Vfoo != \"\" {\n\t\tt.Fatalf(\"value should be default: %s\", result.Vfoo)\n\t}\n\n\tif result.Vother != nil {\n\t\tt.Fatalf(\"Vother should be nil: %s\", result.Vother)\n\t}\n}\n\n// GH-10\nfunc TestDecode_mapInterfaceInterface(t *testing.T) {\n\tinput := map[interface{}]interface{}{\n\t\t\"vfoo\":   nil,\n\t\t\"vother\": nil,\n\t}\n\n\tvar result Map\n\terr := Decode(input, &result)\n\tif err != nil {\n\t\tt.Fatalf(\"should not error: %s\", err)\n\t}\n\n\tif result.Vfoo != \"\" {\n\t\tt.Fatalf(\"value should be default: %s\", result.Vfoo)\n\t}\n\n\tif result.Vother != nil {\n\t\tt.Fatalf(\"Vother should be nil: %s\", result.Vother)\n\t}\n}\n"
  },
  {
    "path": "mapstructure_examples_test.go",
    "content": "package mapstructure\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\nfunc ExampleDecode() {\n\ttype Person struct {\n\t\tName   string\n\t\tAge    int\n\t\tEmails []string\n\t\tExtra  map[string]string\n\t}\n\n\t// This input can come from anywhere, but typically comes from\n\t// something like decoding JSON where we're not quite sure of the\n\t// struct initially.\n\tinput := map[string]interface{}{\n\t\t\"name\":   \"Mitchell\",\n\t\t\"age\":    91,\n\t\t\"emails\": []string{\"one\", \"two\", \"three\"},\n\t\t\"extra\": map[string]string{\n\t\t\t\"twitter\": \"mitchellh\",\n\t\t},\n\t}\n\n\tvar result Person\n\terr := Decode(input, &result)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Printf(\"%#v\", result)\n\t// Output:\n\t// mapstructure.Person{Name:\"Mitchell\", Age:91, Emails:[]string{\"one\", \"two\", \"three\"}, Extra:map[string]string{\"twitter\":\"mitchellh\"}}\n}\n\nfunc ExampleDecode_errors() {\n\ttype Person struct {\n\t\tName   string\n\t\tAge    int\n\t\tEmails []string\n\t\tExtra  map[string]string\n\t}\n\n\t// This input can come from anywhere, but typically comes from\n\t// something like decoding JSON where we're not quite sure of the\n\t// struct initially.\n\tinput := map[string]interface{}{\n\t\t\"name\":   123,\n\t\t\"age\":    \"bad value\",\n\t\t\"emails\": []int{1, 2, 3},\n\t}\n\n\tvar result Person\n\terr := Decode(input, &result)\n\tif err == nil {\n\t\tpanic(\"should have an error\")\n\t}\n\n\tfmt.Println(err.Error())\n\t// Output:\n\t// 5 error(s) decoding:\n\t//\n\t// * 'Name' expected type 'string', got unconvertible type 'int'\n\t// * 'Age' expected type 'int', got unconvertible type 'string'\n\t// * 'Emails[0]' expected type 'string', got unconvertible type 'int'\n\t// * 'Emails[1]' expected type 'string', got unconvertible type 'int'\n\t// * 'Emails[2]' expected type 'string', got unconvertible type 'int'\n}\n\nfunc ExampleDecode_metadata() {\n\ttype Person struct {\n\t\tName string\n\t\tAge  int\n\t}\n\n\t// This input can come from anywhere, but typically comes from\n\t// something like decoding JSON where we're not quite sure of the\n\t// struct initially.\n\tinput := map[string]interface{}{\n\t\t\"name\":  \"Mitchell\",\n\t\t\"age\":   91,\n\t\t\"email\": \"foo@bar.com\",\n\t}\n\n\t// For metadata, we make a more advanced DecoderConfig so we can\n\t// more finely configure the decoder that is used. In this case, we\n\t// just tell the decoder we want to track metadata.\n\tvar md Metadata\n\tvar result Person\n\tconfig := &DecoderConfig{\n\t\tMetadata: &md,\n\t\tResult:   &result,\n\t}\n\n\tdecoder, err := NewDecoder(config)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tif err := decoder.Decode(input); err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Printf(\"Unused keys: %#v\", md.Unused)\n\t// Output:\n\t// Unused keys: []string{\"email\"}\n}\n\nfunc ExampleDecode_weaklyTypedInput() {\n\ttype Person struct {\n\t\tName   string\n\t\tAge    int\n\t\tEmails []string\n\t}\n\n\t// This input can come from anywhere, but typically comes from\n\t// something like decoding JSON, generated by a weakly typed language\n\t// such as PHP.\n\tinput := map[string]interface{}{\n\t\t\"name\":   123,                      // number => string\n\t\t\"age\":    \"42\",                     // string => number\n\t\t\"emails\": map[string]interface{}{}, // empty map => empty array\n\t}\n\n\tvar result Person\n\tconfig := &DecoderConfig{\n\t\tWeaklyTypedInput: true,\n\t\tResult:           &result,\n\t}\n\n\tdecoder, err := NewDecoder(config)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\terr = decoder.Decode(input)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Printf(\"%#v\", result)\n\t// Output: mapstructure.Person{Name:\"123\", Age:42, Emails:[]string{}}\n}\n\nfunc ExampleDecodePath() {\n\tvar document string = `{\n    \"userContext\": {\n        \"conversationCredentials\": {\n            \"sessionToken\": \"06142010_1:75bf6a413327dd71ebe8f3f30c5a4210a9b11e93c028d6e11abfca7ff\"\n        },\n        \"valid\": true,\n        \"isPasswordExpired\": false,\n        \"cobrandId\": 10000004,\n        \"channelId\": -1,\n        \"locale\": \"en_US\",\n        \"tncVersion\": 2,\n        \"applicationId\": \"17CBE222A42161A3FF450E47CF4C1A00\",\n        \"cobrandConversationCredentials\": {\n            \"sessionToken\": \"06142010_1:b8d011fefbab8bf1753391b074ffedf9578612d676ed2b7f073b5785b\"\n        },\n        \"preferenceInfo\": {\n            \"currencyCode\": \"USD\",\n            \"timeZone\": \"PST\",\n            \"dateFormat\": \"MM/dd/yyyy\",\n            \"currencyNotationType\": {\n                \"currencyNotationType\": \"SYMBOL\"\n            },\n            \"numberFormat\": {\n                \"decimalSeparator\": \".\",\n                \"groupingSeparator\": \",\",\n                \"groupPattern\": \"###,##0.##\"\n            }\n        }\n    },\n    \"lastLoginTime\": 1375686841,\n    \"loginCount\": 299,\n    \"passwordRecovered\": false,\n    \"emailAddress\": \"johndoe@email.com\",\n    \"loginName\": \"sptest1\",\n    \"userId\": 10483860,\n    \"userType\":\n        {\n        \"userTypeId\": 1,\n        \"userTypeName\": \"normal_user\"\n        }\n}`\n\n\ttype UserType struct {\n\t\tUserTypeId   int\n\t\tUserTypeName string\n\t}\n\n\ttype NumberFormat struct {\n\t\tDecimalSeparator  string `jpath:\"userContext.preferenceInfo.numberFormat.decimalSeparator\"`\n\t\tGroupingSeparator string `jpath:\"userContext.preferenceInfo.numberFormat.groupingSeparator\"`\n\t\tGroupPattern      string `jpath:\"userContext.preferenceInfo.numberFormat.groupPattern\"`\n\t}\n\n\ttype User struct {\n\t\tSession      string   `jpath:\"userContext.cobrandConversationCredentials.sessionToken\"`\n\t\tCobrandId    int      `jpath:\"userContext.cobrandId\"`\n\t\tUserType     UserType `jpath:\"userType\"`\n\t\tLoginName    string   `jpath:\"loginName\"`\n\t\tNumberFormat          // This can also be a pointer to the struct (*NumberFormat)\n\t}\n\n\tdocScript := []byte(document)\n\tvar docMap map[string]interface{}\n\tjson.Unmarshal(docScript, &docMap)\n\n\tvar user User\n\tDecodePath(docMap, &user)\n\n\tfmt.Printf(\"%#v\", user)\n\t// Output:\n\t// mapstructure.User{Session:\"06142010_1:b8d011fefbab8bf1753391b074ffedf9578612d676ed2b7f073b5785b\", CobrandId:10000004, UserType:mapstructure.UserType{UserTypeId:1, UserTypeName:\"normal_user\"}, LoginName:\"sptest1\", NumberFormat:mapstructure.NumberFormat{DecimalSeparator:\".\", GroupingSeparator:\",\", GroupPattern:\"###,##0.##\"}}\n}\n\nfunc ExampleDecodeSlicePath() {\n\tvar document = `[{\"name\":\"bill\"},{\"name\":\"lisa\"}]`\n\n\ttype NameDoc struct {\n\t\tName string `jpath:\"name\"`\n\t}\n\n\tsliceScript := []byte(document)\n\tvar sliceMap []map[string]interface{}\n\tjson.Unmarshal(sliceScript, &sliceMap)\n\n\tvar myslice []NameDoc\n\tDecodeSlicePath(sliceMap, &myslice)\n\n\tfmt.Printf(\"%#v\", myslice)\n\t// Output:\n\t// []mapstructure.NameDoc{mapstructure.NameDoc{Name:\"bill\"}, mapstructure.NameDoc{Name:\"lisa\"}}\n}\n\nfunc ExampleDecodeWithEmbeddedSlice() {\n\tvar document string = `{\n\t  \"cobrandId\": 10010352,\n\t  \"channelId\": -1,\n\t  \"locale\": \"en_US\",\n\t  \"tncVersion\": 2,\n\t  \"categories\":[\"rabbit\",\"bunny\",\"frog\"],\n\t  \"people\": [\n\t \t{\n\t\t\t\"name\": \"jack\",\n\t\t\t\"age\": {\n\t\t\t\t\"birth\":10,\n\t\t\t\t\"year\":2000,\n\t\t\t\t\"animals\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"barks\":\"yes\",\n\t\t\t\t\t\t\"tail\":\"yes\"\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"barks\":\"no\",\n\t\t\t\t\t\t\"tail\":\"yes\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"name\": \"jill\",\n\t\t\t\"age\": {\n\t\t\t\t\"birth\":11,\n\t\t\t\t\"year\":2001\n\t\t\t}\n\t\t}\n\t  ]\n}`\n\n\ttype Animal struct {\n\t\tBarks string `jpath:\"barks\"`\n\t}\n\n\ttype People struct {\n\t\tAge     int      `jpath:\"age.birth\"` // jpath is relative to the array\n\t\tAnimals []Animal `jpath:\"age.animals\"`\n\t}\n\n\ttype Items struct {\n\t\tCategories []string `jpath:\"categories\"`\n\t\tPeoples    []People `jpath:\"people\"` // Specify the location of the array\n\t}\n\n\tdocScript := []byte(document)\n\tvar docMap map[string]interface{}\n\tjson.Unmarshal(docScript, &docMap)\n\n\tvar items Items\n\tDecodePath(docMap, &items)\n\n\tfmt.Printf(\"%#v\", items)\n\t// Output:\n\t// mapstructure.Items{Categories:[]string{\"rabbit\", \"bunny\", \"frog\"}, Peoples:[]mapstructure.People{mapstructure.People{Age:10, Animals:[]mapstructure.Animal{mapstructure.Animal{Barks:\"yes\"}, mapstructure.Animal{Barks:\"no\"}}}, mapstructure.People{Age:11, Animals:[]mapstructure.Animal(nil)}}}\n}\n\nfunc ExampleDecodeWithAbstractField() {\n\tvar document = `{\"Error\":[{\"errorDetail\":\"Invalid Cobrand Credentials\"}]}`\n\n\ttype YodleeError struct {\n\t\tError []map[string]interface{} `jpath:\"Error\"`\n\t}\n\n\ttype CobrandContext struct {\n\t\tYodleeError\n\t}\n\n\tdocScript := []byte(document)\n\tvar docMap map[string]interface{}\n\tjson.Unmarshal(docScript, &docMap)\n\n\tvar cobrandContext CobrandContext\n\tDecodePath(docMap, &cobrandContext)\n\n\tfmt.Printf(\"%#v\", cobrandContext)\n\t// Output:\n\t// mapstructure.CobrandContext{YodleeError:mapstructure.YodleeError{Error:[]map[string]interface {}{map[string]interface {}{\"errorDetail\":\"Invalid Cobrand Credentials\"}}}}\n}\n"
  },
  {
    "path": "mapstructure_test.go",
    "content": "package mapstructure\n\nimport (\n\t\"encoding/json\"\n\t\"reflect\"\n\t\"sort\"\n\t\"testing\"\n)\n\ntype Basic struct {\n\tVstring string\n\tVint    int\n\tVuint   uint\n\tVbool   bool\n\tVfloat  float64\n\tVextra  string\n\tvsilent bool\n\tVdata   interface{}\n}\n\ntype Embedded struct {\n\tBasic\n\tVunique string\n}\n\ntype EmbeddedPointer struct {\n\t*Basic\n\tVunique string\n}\n\ntype EmbeddedSquash struct {\n\tBasic   `mapstructure:\",squash\"`\n\tVunique string\n}\n\ntype Map struct {\n\tVfoo   string\n\tVother map[string]string\n}\n\ntype MapOfStruct struct {\n\tValue map[string]Basic\n}\n\ntype Nested struct {\n\tVfoo string\n\tVbar Basic\n}\n\ntype Slice struct {\n\tVfoo string\n\tVbar []string\n}\n\ntype SliceOfStruct struct {\n\tValue []Basic\n}\n\ntype Tagged struct {\n\tExtra string `mapstructure:\"bar,what,what\"`\n\tValue string `mapstructure:\"foo\"`\n}\n\ntype TypeConversionResult struct {\n\tIntToFloat    float32\n\tIntToUint     uint\n\tIntToBool     bool\n\tIntToString   string\n\tUintToInt     int\n\tUintToFloat   float32\n\tUintToBool    bool\n\tUintToString  string\n\tBoolToInt     int\n\tBoolToUint    uint\n\tBoolToFloat   float32\n\tBoolToString  string\n\tFloatToInt    int\n\tFloatToUint   uint\n\tFloatToBool   bool\n\tFloatToString string\n\tStringToInt   int\n\tStringToUint  uint\n\tStringToBool  bool\n\tStringToFloat float32\n\tSliceToMap    map[string]interface{}\n\tMapToSlice    []interface{}\n}\n\nfunc TestBasicTypes(t *testing.T) {\n\tt.Parallel()\n\n\tinput := map[string]interface{}{\n\t\t\"vstring\": \"foo\",\n\t\t\"vint\":    42,\n\t\t\"Vuint\":   42,\n\t\t\"vbool\":   true,\n\t\t\"Vfloat\":  42.42,\n\t\t\"vsilent\": true,\n\t\t\"vdata\":   42,\n\t}\n\n\tvar result Basic\n\terr := Decode(input, &result)\n\tif err != nil {\n\t\tt.Errorf(\"got an err: %s\", err.Error())\n\t\tt.FailNow()\n\t}\n\n\tif result.Vstring != \"foo\" {\n\t\tt.Errorf(\"vstring value should be 'foo': %#v\", result.Vstring)\n\t}\n\n\tif result.Vint != 42 {\n\t\tt.Errorf(\"vint value should be 42: %#v\", result.Vint)\n\t}\n\n\tif result.Vuint != 42 {\n\t\tt.Errorf(\"vuint value should be 42: %#v\", result.Vuint)\n\t}\n\n\tif result.Vbool != true {\n\t\tt.Errorf(\"vbool value should be true: %#v\", result.Vbool)\n\t}\n\n\tif result.Vfloat != 42.42 {\n\t\tt.Errorf(\"vfloat value should be 42.42: %#v\", result.Vfloat)\n\t}\n\n\tif result.Vextra != \"\" {\n\t\tt.Errorf(\"vextra value should be empty: %#v\", result.Vextra)\n\t}\n\n\tif result.vsilent != false {\n\t\tt.Error(\"vsilent should not be set, it is unexported\")\n\t}\n\n\tif result.Vdata != 42 {\n\t\tt.Error(\"vdata should be valid\")\n\t}\n}\n\nfunc TestBasic_IntWithFloat(t *testing.T) {\n\tt.Parallel()\n\n\tinput := map[string]interface{}{\n\t\t\"vint\": float64(42),\n\t}\n\n\tvar result Basic\n\terr := Decode(input, &result)\n\tif err != nil {\n\t\tt.Fatalf(\"got an err: %s\", err)\n\t}\n}\n\nfunc TestDecode_Embedded(t *testing.T) {\n\tt.Parallel()\n\n\tinput := map[string]interface{}{\n\t\t\"vstring\": \"foo\",\n\t\t\"Basic\": map[string]interface{}{\n\t\t\t\"vstring\": \"innerfoo\",\n\t\t},\n\t\t\"vunique\": \"bar\",\n\t}\n\n\tvar result Embedded\n\terr := Decode(input, &result)\n\tif err != nil {\n\t\tt.Fatalf(\"got an err: %s\", err.Error())\n\t}\n\n\tif result.Vstring != \"innerfoo\" {\n\t\tt.Errorf(\"vstring value should be 'innerfoo': %#v\", result.Vstring)\n\t}\n\n\tif result.Vunique != \"bar\" {\n\t\tt.Errorf(\"vunique value should be 'bar': %#v\", result.Vunique)\n\t}\n}\n\nfunc TestDecode_EmbeddedPointer(t *testing.T) {\n\tt.Parallel()\n\n\tinput := map[string]interface{}{\n\t\t\"vstring\": \"foo\",\n\t\t\"Basic\": map[string]interface{}{\n\t\t\t\"vstring\": \"innerfoo\",\n\t\t},\n\t\t\"vunique\": \"bar\",\n\t}\n\n\tvar result EmbeddedPointer\n\terr := Decode(input, &result)\n\tif err == nil {\n\t\tt.Fatal(\"should get error\")\n\t}\n}\n\nfunc TestDecode_EmbeddedSquash(t *testing.T) {\n\tt.Parallel()\n\n\tinput := map[string]interface{}{\n\t\t\"vstring\": \"foo\",\n\t\t\"vunique\": \"bar\",\n\t}\n\n\tvar result EmbeddedSquash\n\terr := Decode(input, &result)\n\tif err != nil {\n\t\tt.Fatalf(\"got an err: %s\", err.Error())\n\t}\n\n\tif result.Vstring != \"foo\" {\n\t\tt.Errorf(\"vstring value should be 'foo': %#v\", result.Vstring)\n\t}\n\n\tif result.Vunique != \"bar\" {\n\t\tt.Errorf(\"vunique value should be 'bar': %#v\", result.Vunique)\n\t}\n}\n\nfunc TestDecode_DecodeHook(t *testing.T) {\n\tt.Parallel()\n\n\tinput := map[string]interface{}{\n\t\t\"vint\": \"WHAT\",\n\t}\n\n\tdecodeHook := func(from reflect.Kind, to reflect.Kind, v interface{}) (interface{}, error) {\n\t\tif from == reflect.String && to != reflect.String {\n\t\t\treturn 5, nil\n\t\t}\n\n\t\treturn v, nil\n\t}\n\n\tvar result Basic\n\tconfig := &DecoderConfig{\n\t\tDecodeHook: decodeHook,\n\t\tResult:     &result,\n\t}\n\n\tdecoder, err := NewDecoder(config)\n\tif err != nil {\n\t\tt.Fatalf(\"err: %s\", err)\n\t}\n\n\terr = decoder.Decode(input)\n\tif err != nil {\n\t\tt.Fatalf(\"got an err: %s\", err)\n\t}\n\n\tif result.Vint != 5 {\n\t\tt.Errorf(\"vint should be 5: %#v\", result.Vint)\n\t}\n}\n\nfunc TestDecode_Nil(t *testing.T) {\n\tt.Parallel()\n\n\tvar input interface{} = nil\n\tresult := Basic{\n\t\tVstring: \"foo\",\n\t}\n\n\terr := Decode(input, &result)\n\tif err != nil {\n\t\tt.Fatalf(\"err: %s\", err)\n\t}\n\n\tif result.Vstring != \"foo\" {\n\t\tt.Fatalf(\"bad: %#v\", result.Vstring)\n\t}\n}\n\nfunc TestDecode_NonStruct(t *testing.T) {\n\tt.Parallel()\n\n\tinput := map[string]interface{}{\n\t\t\"foo\": \"bar\",\n\t\t\"bar\": \"baz\",\n\t}\n\n\tvar result map[string]string\n\terr := Decode(input, &result)\n\tif err != nil {\n\t\tt.Fatalf(\"err: %s\", err)\n\t}\n\n\tif result[\"foo\"] != \"bar\" {\n\t\tt.Fatal(\"foo is not bar\")\n\t}\n}\n\nfunc TestDecode_TypeConversion(t *testing.T) {\n\tinput := map[string]interface{}{\n\t\t\"IntToFloat\":    42,\n\t\t\"IntToUint\":     42,\n\t\t\"IntToBool\":     1,\n\t\t\"IntToString\":   42,\n\t\t\"UintToInt\":     42,\n\t\t\"UintToFloat\":   42,\n\t\t\"UintToBool\":    42,\n\t\t\"UintToString\":  42,\n\t\t\"BoolToInt\":     true,\n\t\t\"BoolToUint\":    true,\n\t\t\"BoolToFloat\":   true,\n\t\t\"BoolToString\":  true,\n\t\t\"FloatToInt\":    42.42,\n\t\t\"FloatToUint\":   42.42,\n\t\t\"FloatToBool\":   42.42,\n\t\t\"FloatToString\": 42.42,\n\t\t\"StringToInt\":   \"42\",\n\t\t\"StringToUint\":  \"42\",\n\t\t\"StringToBool\":  \"1\",\n\t\t\"StringToFloat\": \"42.42\",\n\t\t\"SliceToMap\":    []interface{}{},\n\t\t\"MapToSlice\":    map[string]interface{}{},\n\t}\n\n\texpectedResultStrict := TypeConversionResult{\n\t\tIntToFloat:  42.0,\n\t\tIntToUint:   42,\n\t\tUintToInt:   42,\n\t\tUintToFloat: 42,\n\t\tBoolToInt:   0,\n\t\tBoolToUint:  0,\n\t\tBoolToFloat: 0,\n\t\tFloatToInt:  42,\n\t\tFloatToUint: 42,\n\t}\n\n\texpectedResultWeak := TypeConversionResult{\n\t\tIntToFloat:    42.0,\n\t\tIntToUint:     42,\n\t\tIntToBool:     true,\n\t\tIntToString:   \"42\",\n\t\tUintToInt:     42,\n\t\tUintToFloat:   42,\n\t\tUintToBool:    true,\n\t\tUintToString:  \"42\",\n\t\tBoolToInt:     1,\n\t\tBoolToUint:    1,\n\t\tBoolToFloat:   1,\n\t\tBoolToString:  \"1\",\n\t\tFloatToInt:    42,\n\t\tFloatToUint:   42,\n\t\tFloatToBool:   true,\n\t\tFloatToString: \"42.42\",\n\t\tStringToInt:   42,\n\t\tStringToUint:  42,\n\t\tStringToBool:  true,\n\t\tStringToFloat: 42.42,\n\t\tSliceToMap:    map[string]interface{}{},\n\t\tMapToSlice:    []interface{}{},\n\t}\n\n\t// Test strict type conversion\n\tvar resultStrict TypeConversionResult\n\terr := Decode(input, &resultStrict)\n\tif err == nil {\n\t\tt.Errorf(\"should return an error\")\n\t}\n\tif !reflect.DeepEqual(resultStrict, expectedResultStrict) {\n\t\tt.Errorf(\"expected %v, got: %v\", expectedResultStrict, resultStrict)\n\t}\n\n\t// Test weak type conversion\n\tvar decoder *Decoder\n\tvar resultWeak TypeConversionResult\n\n\tconfig := &DecoderConfig{\n\t\tWeaklyTypedInput: true,\n\t\tResult:           &resultWeak,\n\t}\n\n\tdecoder, err = NewDecoder(config)\n\tif err != nil {\n\t\tt.Fatalf(\"err: %s\", err)\n\t}\n\n\terr = decoder.Decode(input)\n\tif err != nil {\n\t\tt.Fatalf(\"got an err: %s\", err)\n\t}\n\n\tif !reflect.DeepEqual(resultWeak, expectedResultWeak) {\n\t\tt.Errorf(\"expected \\n%#v, got: \\n%#v\", expectedResultWeak, resultWeak)\n\t}\n}\n\nfunc TestDecoder_ErrorUnused(t *testing.T) {\n\tt.Parallel()\n\n\tinput := map[string]interface{}{\n\t\t\"vstring\": \"hello\",\n\t\t\"foo\":     \"bar\",\n\t}\n\n\tvar result Basic\n\tconfig := &DecoderConfig{\n\t\tErrorUnused: true,\n\t\tResult:      &result,\n\t}\n\n\tdecoder, err := NewDecoder(config)\n\tif err != nil {\n\t\tt.Fatalf(\"err: %s\", err)\n\t}\n\n\terr = decoder.Decode(input)\n\tif err == nil {\n\t\tt.Fatal(\"expected error\")\n\t}\n}\n\nfunc TestMap(t *testing.T) {\n\tt.Parallel()\n\n\tinput := map[string]interface{}{\n\t\t\"vfoo\": \"foo\",\n\t\t\"vother\": map[interface{}]interface{}{\n\t\t\t\"foo\": \"foo\",\n\t\t\t\"bar\": \"bar\",\n\t\t},\n\t}\n\n\tvar result Map\n\terr := Decode(input, &result)\n\tif err != nil {\n\t\tt.Fatalf(\"got an error: %s\", err)\n\t}\n\n\tif result.Vfoo != \"foo\" {\n\t\tt.Errorf(\"vfoo value should be 'foo': %#v\", result.Vfoo)\n\t}\n\n\tif result.Vother == nil {\n\t\tt.Fatal(\"vother should not be nil\")\n\t}\n\n\tif len(result.Vother) != 2 {\n\t\tt.Error(\"vother should have two items\")\n\t}\n\n\tif result.Vother[\"foo\"] != \"foo\" {\n\t\tt.Errorf(\"'foo' key should be foo, got: %#v\", result.Vother[\"foo\"])\n\t}\n\n\tif result.Vother[\"bar\"] != \"bar\" {\n\t\tt.Errorf(\"'bar' key should be bar, got: %#v\", result.Vother[\"bar\"])\n\t}\n}\n\nfunc TestMapOfStruct(t *testing.T) {\n\tt.Parallel()\n\n\tinput := map[string]interface{}{\n\t\t\"value\": map[string]interface{}{\n\t\t\t\"foo\": map[string]string{\"vstring\": \"one\"},\n\t\t\t\"bar\": map[string]string{\"vstring\": \"two\"},\n\t\t},\n\t}\n\n\tvar result MapOfStruct\n\terr := Decode(input, &result)\n\tif err != nil {\n\t\tt.Fatalf(\"got an err: %s\", err)\n\t}\n\n\tif result.Value == nil {\n\t\tt.Fatal(\"value should not be nil\")\n\t}\n\n\tif len(result.Value) != 2 {\n\t\tt.Error(\"value should have two items\")\n\t}\n\n\tif result.Value[\"foo\"].Vstring != \"one\" {\n\t\tt.Errorf(\"foo value should be 'one', got: %s\", result.Value[\"foo\"].Vstring)\n\t}\n\n\tif result.Value[\"bar\"].Vstring != \"two\" {\n\t\tt.Errorf(\"bar value should be 'two', got: %s\", result.Value[\"bar\"].Vstring)\n\t}\n}\n\nfunc TestNestedType(t *testing.T) {\n\tt.Parallel()\n\n\tinput := map[string]interface{}{\n\t\t\"vfoo\": \"foo\",\n\t\t\"vbar\": map[string]interface{}{\n\t\t\t\"vstring\": \"foo\",\n\t\t\t\"vint\":    42,\n\t\t\t\"vbool\":   true,\n\t\t},\n\t}\n\n\tvar result Nested\n\terr := Decode(input, &result)\n\tif err != nil {\n\t\tt.Fatalf(\"got an err: %s\", err.Error())\n\t}\n\n\tif result.Vfoo != \"foo\" {\n\t\tt.Errorf(\"vfoo value should be 'foo': %#v\", result.Vfoo)\n\t}\n\n\tif result.Vbar.Vstring != \"foo\" {\n\t\tt.Errorf(\"vstring value should be 'foo': %#v\", result.Vbar.Vstring)\n\t}\n\n\tif result.Vbar.Vint != 42 {\n\t\tt.Errorf(\"vint value should be 42: %#v\", result.Vbar.Vint)\n\t}\n\n\tif result.Vbar.Vbool != true {\n\t\tt.Errorf(\"vbool value should be true: %#v\", result.Vbar.Vbool)\n\t}\n\n\tif result.Vbar.Vextra != \"\" {\n\t\tt.Errorf(\"vextra value should be empty: %#v\", result.Vbar.Vextra)\n\t}\n}\n\nfunc TestNestedTypePointer(t *testing.T) {\n\tt.Parallel()\n\n\tinput := map[string]interface{}{\n\t\t\"vfoo\": \"foo\",\n\t\t\"vbar\": &map[string]interface{}{\n\t\t\t\"vstring\": \"foo\",\n\t\t\t\"vint\":    42,\n\t\t\t\"vbool\":   true,\n\t\t},\n\t}\n\n\tvar result Nested\n\terr := Decode(input, &result)\n\tif err != nil {\n\t\tt.Fatalf(\"got an err: %s\", err.Error())\n\t}\n\n\tif result.Vfoo != \"foo\" {\n\t\tt.Errorf(\"vfoo value should be 'foo': %#v\", result.Vfoo)\n\t}\n\n\tif result.Vbar.Vstring != \"foo\" {\n\t\tt.Errorf(\"vstring value should be 'foo': %#v\", result.Vbar.Vstring)\n\t}\n\n\tif result.Vbar.Vint != 42 {\n\t\tt.Errorf(\"vint value should be 42: %#v\", result.Vbar.Vint)\n\t}\n\n\tif result.Vbar.Vbool != true {\n\t\tt.Errorf(\"vbool value should be true: %#v\", result.Vbar.Vbool)\n\t}\n\n\tif result.Vbar.Vextra != \"\" {\n\t\tt.Errorf(\"vextra value should be empty: %#v\", result.Vbar.Vextra)\n\t}\n}\n\nfunc TestSlice(t *testing.T) {\n\tt.Parallel()\n\n\tinputStringSlice := map[string]interface{}{\n\t\t\"vfoo\": \"foo\",\n\t\t\"vbar\": []string{\"foo\", \"bar\", \"baz\"},\n\t}\n\n\tinputStringSlicePointer := map[string]interface{}{\n\t\t\"vfoo\": \"foo\",\n\t\t\"vbar\": &[]string{\"foo\", \"bar\", \"baz\"},\n\t}\n\n\toutputStringSlice := &Slice{\n\t\t\"foo\",\n\t\t[]string{\"foo\", \"bar\", \"baz\"},\n\t}\n\n\ttestSliceInput(t, inputStringSlice, outputStringSlice)\n\ttestSliceInput(t, inputStringSlicePointer, outputStringSlice)\n}\n\nfunc TestSliceOfStruct(t *testing.T) {\n\tt.Parallel()\n\n\tinput := map[string]interface{}{\n\t\t\"value\": []map[string]interface{}{\n\t\t\t{\"vstring\": \"one\"},\n\t\t\t{\"vstring\": \"two\"},\n\t\t},\n\t}\n\n\tvar result SliceOfStruct\n\terr := Decode(input, &result)\n\tif err != nil {\n\t\tt.Fatalf(\"got unexpected error: %s\", err)\n\t}\n\n\tif len(result.Value) != 2 {\n\t\tt.Fatalf(\"expected two values, got %d\", len(result.Value))\n\t}\n\n\tif result.Value[0].Vstring != \"one\" {\n\t\tt.Errorf(\"first value should be 'one', got: %s\", result.Value[0].Vstring)\n\t}\n\n\tif result.Value[1].Vstring != \"two\" {\n\t\tt.Errorf(\"second value should be 'two', got: %s\", result.Value[1].Vstring)\n\t}\n}\n\nfunc TestInvalidType(t *testing.T) {\n\tt.Parallel()\n\n\tinput := map[string]interface{}{\n\t\t\"vstring\": 42,\n\t}\n\n\tvar result Basic\n\terr := Decode(input, &result)\n\tif err == nil {\n\t\tt.Fatal(\"error should exist\")\n\t}\n\n\tderr, ok := err.(*Error)\n\tif !ok {\n\t\tt.Fatalf(\"error should be kind of Error, instead: %#v\", err)\n\t}\n\n\tif derr.Errors[0] != \"'Vstring' expected type 'string', got unconvertible type 'int'\" {\n\t\tt.Errorf(\"got unexpected error: %s\", err)\n\t}\n}\n\nfunc TestMetadata(t *testing.T) {\n\tt.Parallel()\n\n\tinput := map[string]interface{}{\n\t\t\"vfoo\": \"foo\",\n\t\t\"vbar\": map[string]interface{}{\n\t\t\t\"vstring\": \"foo\",\n\t\t\t\"Vuint\":   42,\n\t\t\t\"foo\":     \"bar\",\n\t\t},\n\t\t\"bar\": \"nil\",\n\t}\n\n\tvar md Metadata\n\tvar result Nested\n\tconfig := &DecoderConfig{\n\t\tMetadata: &md,\n\t\tResult:   &result,\n\t}\n\n\tdecoder, err := NewDecoder(config)\n\tif err != nil {\n\t\tt.Fatalf(\"err: %s\", err)\n\t}\n\n\terr = decoder.Decode(input)\n\tif err != nil {\n\t\tt.Fatalf(\"err: %s\", err.Error())\n\t}\n\n\texpectedKeys := []string{\"Vfoo\", \"Vbar.Vstring\", \"Vbar.Vuint\", \"Vbar\"}\n\tif !reflect.DeepEqual(md.Keys, expectedKeys) {\n\t\tt.Fatalf(\"bad keys: %#v\", md.Keys)\n\t}\n\n\texpectedUnused := []string{\"Vbar.foo\", \"bar\"}\n\tif !reflect.DeepEqual(md.Unused, expectedUnused) {\n\t\tt.Fatalf(\"bad unused: %#v\", md.Unused)\n\t}\n}\n\nfunc TestMetadata_Embedded(t *testing.T) {\n\tt.Parallel()\n\n\tinput := map[string]interface{}{\n\t\t\"vstring\": \"foo\",\n\t\t\"vunique\": \"bar\",\n\t}\n\n\tvar md Metadata\n\tvar result EmbeddedSquash\n\tconfig := &DecoderConfig{\n\t\tMetadata: &md,\n\t\tResult:   &result,\n\t}\n\n\tdecoder, err := NewDecoder(config)\n\tif err != nil {\n\t\tt.Fatalf(\"err: %s\", err)\n\t}\n\n\terr = decoder.Decode(input)\n\tif err != nil {\n\t\tt.Fatalf(\"err: %s\", err.Error())\n\t}\n\n\texpectedKeys := []string{\"Vstring\", \"Vunique\"}\n\n\tsort.Strings(md.Keys)\n\tif !reflect.DeepEqual(md.Keys, expectedKeys) {\n\t\tt.Fatalf(\"bad keys: %#v\", md.Keys)\n\t}\n\n\texpectedUnused := []string{}\n\tif !reflect.DeepEqual(md.Unused, expectedUnused) {\n\t\tt.Fatalf(\"bad unused: %#v\", md.Unused)\n\t}\n}\n\nfunc TestNonPtrValue(t *testing.T) {\n\tt.Parallel()\n\n\terr := Decode(map[string]interface{}{}, Basic{})\n\tif err == nil {\n\t\tt.Fatal(\"error should exist\")\n\t}\n\n\tif err.Error() != \"result must be a pointer\" {\n\t\tt.Errorf(\"got unexpected error: %s\", err)\n\t}\n}\n\nfunc TestTagged(t *testing.T) {\n\tt.Parallel()\n\n\tinput := map[string]interface{}{\n\t\t\"foo\": \"bar\",\n\t\t\"bar\": \"value\",\n\t}\n\n\tvar result Tagged\n\terr := Decode(input, &result)\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %s\", err)\n\t}\n\n\tif result.Value != \"bar\" {\n\t\tt.Errorf(\"value should be 'bar', got: %#v\", result.Value)\n\t}\n\n\tif result.Extra != \"value\" {\n\t\tt.Errorf(\"extra should be 'value', got: %#v\", result.Extra)\n\t}\n}\n\nfunc testSliceInput(t *testing.T, input map[string]interface{}, expected *Slice) {\n\tvar result Slice\n\terr := Decode(input, &result)\n\tif err != nil {\n\t\tt.Fatalf(\"got error: %s\", err)\n\t}\n\n\tif result.Vfoo != expected.Vfoo {\n\t\tt.Errorf(\"Vfoo expected '%s', got '%s'\", expected.Vfoo, result.Vfoo)\n\t}\n\n\tif result.Vbar == nil {\n\t\tt.Fatalf(\"Vbar a slice, got '%#v'\", result.Vbar)\n\t}\n\n\tif len(result.Vbar) != len(expected.Vbar) {\n\t\tt.Errorf(\"Vbar length should be %d, got %d\", len(expected.Vbar), len(result.Vbar))\n\t}\n\n\tfor i, v := range result.Vbar {\n\t\tif v != expected.Vbar[i] {\n\t\t\tt.Errorf(\n\t\t\t\t\"Vbar[%d] should be '%#v', got '%#v'\",\n\t\t\t\ti, expected.Vbar[i], v)\n\t\t}\n\t}\n}\n\nfunc TestDecodePath(t *testing.T) {\n\tvar document string = `{\n    \"userContext\": {\n        \"cobrandId\": 10000004,\n        \"channelId\": -1,\n        \"locale\": \"en_US\",\n        \"tncVersion\": 2,\n        \"applicationId\": \"17CBE222A42161A3FF450E47CF4C1A00\",\n        \"cobrandConversationCredentials\": {\n            \"sessionToken\": \"06142010_1:b8d011fefbab8bf1753391b074ffedf9578612d676ed2b7f073b5785b\"\n        },\n\t\t\"preferenceInfo\": {\n            \"currencyCode\": \"USD\",\n            \"timeZone\": \"PST\",\n            \"dateFormat\": \"MM/dd/yyyy\",\n            \"currencyNotationType\": {\n                \"currencyNotationType\": \"SYMBOL\"\n            },\n            \"numberFormat\": {\n                \"decimalSeparator\": \".\",\n                \"groupingSeparator\": \",\",\n                \"groupPattern\": \"###,##0.##\"\n            }\n        }\n    },\n    \"loginName\": \"sptest1\",\n    \"userId\": 10483860,\n    \"userType\":\n        {\n        \"userTypeId\": 1,\n        \"userTypeName\": \"normal_user\"\n        }\n}`\n\n\ttype UserType struct {\n\t\tUserTypeId   int\n\t\tUserTypeName string\n\t}\n\n\ttype NumberFormat struct {\n\t\tDecimalSeparator  string `jpath:\"userContext.preferenceInfo.numberFormat.decimalSeparator\"`\n\t\tGroupingSeparator string `jpath:\"userContext.preferenceInfo.numberFormat.groupingSeparator\"`\n\t\tGroupPattern      string `jpath:\"userContext.preferenceInfo.numberFormat.groupPattern\"`\n\t}\n\n\ttype User struct {\n\t\tSession   string   `jpath:\"userContext.cobrandConversationCredentials.sessionToken\"`\n\t\tCobrandId int      `jpath:\"userContext.cobrandId\"`\n\t\tUserType  UserType `jpath:\"userType\"`\n\t\tLoginName string   `jpath:\"loginName\"`\n\t\t*NumberFormat\n\t}\n\n\tdocScript := []byte(document)\n\tvar docMap map[string]interface{}\n\terr := json.Unmarshal(docScript, &docMap)\n\tif err != nil {\n\t\tt.Fatalf(\"Unable To Unmarshal Test Document, %s\", err)\n\t}\n\n\tvar user User\n\tDecodePath(docMap, &user)\n\n\tsession := \"06142010_1:b8d011fefbab8bf1753391b074ffedf9578612d676ed2b7f073b5785b\"\n\tif user.Session != session {\n\t\tt.Errorf(\"user.Session should be '%s', we got '%s'\", session, user.Session)\n\t}\n\n\tcobrandId := 10000004\n\tif user.CobrandId != cobrandId {\n\t\tt.Errorf(\"user.CobrandId should be '%d', we got '%d'\", cobrandId, user.CobrandId)\n\t}\n\n\tloginName := \"sptest1\"\n\tif user.LoginName != loginName {\n\t\tt.Errorf(\"user.LoginName should be '%s', we got '%s'\", loginName, user.LoginName)\n\t}\n\n\tuserTypeId := 1\n\tif user.UserType.UserTypeId != userTypeId {\n\t\tt.Errorf(\"user.UserType.UserTypeId should be '%d', we got '%d'\", userTypeId, user.UserType.UserTypeId)\n\t}\n\n\tuserTypeName := \"normal_user\"\n\tif user.UserType.UserTypeName != userTypeName {\n\t\tt.Errorf(\"user.UserType.UserTypeName should be '%s', we got '%s'\", userTypeName, user.UserType.UserTypeName)\n\t}\n\n\tdecimalSeparator := \".\"\n\tif user.NumberFormat.DecimalSeparator != decimalSeparator {\n\t\tt.Errorf(\"user.NumberFormat.DecimalSeparator should be '%s', we got '%s'\", decimalSeparator, user.NumberFormat.DecimalSeparator)\n\t}\n\n\tgroupingSeparator := \",\"\n\tif user.NumberFormat.GroupingSeparator != groupingSeparator {\n\t\tt.Errorf(\"user.NumberFormat.GroupingSeparator should be '%s', we got '%s'\", groupingSeparator, user.NumberFormat.GroupingSeparator)\n\t}\n\n\tgroupPattern := \"###,##0.##\"\n\tif user.NumberFormat.GroupPattern != groupPattern {\n\t\tt.Errorf(\"user.NumberFormat.GroupPattern should be '%s', we got '%s'\", groupPattern, user.NumberFormat.GroupPattern)\n\t}\n}\n\nfunc TestDecodeSlicePath(t *testing.T) {\n\tvar document = `[{\"name\":\"bill\"},{\"name\":\"lisa\"}]`\n\n\ttype NameDoc struct {\n\t\tName string `jpath:\"name\"`\n\t}\n\n\tsliceScript := []byte(document)\n\tvar sliceMap []map[string]interface{}\n\tjson.Unmarshal(sliceScript, &sliceMap)\n\n\tvar myslice1 []NameDoc\n\terr1 := DecodeSlicePath(sliceMap, &myslice1)\n\n\tvar myslice2 []*NameDoc\n\terr2 := DecodeSlicePath(sliceMap, &myslice2)\n\n\tname1 := \"bill\"\n\tname2 := \"lisa\"\n\n\tif err1 != nil {\n\t\tt.Fatal(err1)\n\t}\n\n\tif err2 != nil {\n\t\tt.Fatal(err1)\n\t}\n\n\tif myslice1[0].Name != name1 {\n\t\tt.Errorf(\"myslice1[0].Name should be '%s', we got '%s'\", name1, myslice1[0].Name)\n\t}\n\n\tif myslice1[1].Name != name2 {\n\t\tt.Errorf(\"myslice1[1].Name should be '%s', we got '%s'\", name1, myslice1[1].Name)\n\t}\n\n\tif myslice2[0].Name != name1 {\n\t\tt.Errorf(\"myslice2[0].Name should be '%s', we got '%s'\", name1, myslice1[0].Name)\n\t}\n\n\tif myslice2[1].Name != name2 {\n\t\tt.Errorf(\"myslice1[1].Name should be '%s', we got '%s'\", name2, myslice2[1].Name)\n\t}\n}\n\nfunc TestDecodeWithEmbeddedSlice(t *testing.T) {\n\tvar document string = `{\n\t\t\"cobrandId\": 10010352,\n\t\t\"channelId\": -1,\n\t\t\"locale\": \"en_US\",\n\t\t\"tncVersion\": 2,\n\t\t\"categories\":[\"rabbit\",\"bunny\",\"frog\"],\n\t\t\"people\": [\n\t\t\t{\n\t\t\t\t\"name\": \"jack\",\n\t\t\t\t\"age\": {\n\t\t\t\t\"birth\":10,\n\t\t\t\t\"year\":2000,\n\t\t\t\t\"animals\": [\n\t\t\t\t\t{\n\t\t\t\t\t\"barks\":\"yes\",\n\t\t\t\t\t\"tail\":\"yes\"\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\"barks\":\"no\",\n\t\t\t\t\t\"tail\":\"yes\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"jill\",\n\t\t\t\t\"age\": {\n\t\t\t\t\t\"birth\":11,\n\t\t\t\t\t\"year\":2001\n\t\t\t\t}\n\t\t\t}\n\t\t]\n}`\n\n\ttype Animal struct {\n\t\tBarks string `jpath:\"barks\"`\n\t}\n\n\ttype People struct {\n\t\tAge     int      `jpath:\"age.birth\"`\n\t\tAnimals []Animal `jpath:\"age.animals\"`\n\t}\n\n\ttype Items struct {\n\t\tCategories []string `jpath:\"categories\"`\n\t\tPeoples    []People `jpath:\"people\"`\n\t}\n\n\tdocScript := []byte(document)\n\tvar docMap map[string]interface{}\n\tjson.Unmarshal(docScript, &docMap)\n\n\titems := Items{}\n\tDecodePath(docMap, &items)\n\n\tif len(items.Categories) != 3 {\n\t\tt.Error(\"items.Categories did not decode\")\n\t\treturn\n\t}\n\n\tif len(items.Peoples) != 2 {\n\t\tt.Error(\"items.Peoples did not decode\")\n\t\treturn\n\t}\n\n\tif len(items.Peoples[0].Animals) != 2 {\n\t\tt.Error(\"items.Peoples[0].Animals did not decode\")\n\t\treturn\n\t}\n\n\tage := 10\n\tif items.Peoples[0].Age != 10 {\n\t\tt.Errorf(\"items.Peoples[0].Age should be '%d', we got '%s'\", age, items.Peoples[0].Age)\n\t}\n\n\tbarks := \"yes\"\n\tif items.Peoples[0].Animals[0].Barks != barks {\n\t\tt.Errorf(\"items.Peoples[0].Animals[0].Barks should be '%d', we got '%s'\", barks, items.Peoples[0].Animals[0].Barks)\n\t}\n}\n\nfunc TestDecodeWithAbstractField(t *testing.T) {\n\tvar document = `{\"Error\":[{\"errorDetail\":\"Invalid Cobrand Credentials\"}]}`\n\n\ttype AnError struct {\n\t\tError []map[string]interface{} `jpath:\"Error\"`\n\t}\n\n\ttype Context struct {\n\t\t*AnError\n\t}\n\n\tdocScript := []byte(document)\n\tvar docMap map[string]interface{}\n\tjson.Unmarshal(docScript, &docMap)\n\n\tcontext := Context{}\n\tDecodePath(docMap, &context)\n\n\terrorDetail := \"Invalid Cobrand Credentials\"\n\tif context.Error[0][\"errorDetail\"].(string) != errorDetail {\n\t\tt.Errorf(\"context.Error[0][\\\"errorDetail\\\"] should be '%s', we got '%s'\", errorDetail, context.Error[0][\"errorDetail\"].(string))\n\t}\n}\n\nfunc TestDecodePointerToPointer(t *testing.T) {\n\tvar document = `{\"Error\":[{\"errorDetail\":\"Invalid Cobrand Credentials\"}]}`\n\n\ttype AnError struct {\n\t\tError []map[string]interface{} `jpath:\"Error\"`\n\t}\n\n\ttype APointerError struct {\n\t\t*AnError\n\t}\n\n\ttype Context struct {\n\t\t*APointerError\n\t}\n\n\tdocScript := []byte(document)\n\tvar docMap map[string]interface{}\n\tjson.Unmarshal(docScript, &docMap)\n\n\tvar context Context\n\tDecodePath(docMap, &context)\n\n\terrorDetail := \"Invalid Cobrand Credentials\"\n\tif context.Error != nil {\n\t\tif context.Error[0][\"errorDetail\"].(string) != errorDetail {\n\t\t\tt.Errorf(\"context.Error[0][\\\"errorDetail\\\"] should be '%s', we got '%s'\", errorDetail, context.Error[0][\"errorDetail\"].(string))\n\t\t}\n\t}\n}\n"
  }
]