package mapstructure import ( "fmt" ) func ExampleDecode() { type Person struct { Name string Age int Emails []string Extra map[string]string } // This input can come from anywhere, but typically comes from // something like decoding JSON where we're not quite sure of the // struct initially. input := map[string]interface{}{ "name": "Mitchell", "age": 91, "emails": []string{"one", "two", "three"}, "extra": map[string]string{ "twitter": "mitchellh", }, } var result Person err := Decode(input, &result) if err != nil { panic(err) } fmt.Printf("%#v", result) // Output: // mapstructure.Person{Name:"Mitchell", Age:91, Emails:[]string{"one", "two", "three"}, Extra:map[string]string{"twitter":"mitchellh"}} } func ExampleDecode_errors() { type Person struct { Name string Age int Emails []string Extra map[string]string } // This input can come from anywhere, but typically comes from // something like decoding JSON where we're not quite sure of the // struct initially. input := map[string]interface{}{ "name": 123, "age": "bad value", "emails": []int{1, 2, 3}, } var result Person err := Decode(input, &result) if err == nil { panic("should have an error") } fmt.Println(err.Error()) // Output: // 5 error(s) decoding: // // * 'Age' expected type 'int', got unconvertible type 'string' // * 'Emails[0]' expected type 'string', got unconvertible type 'int' // * 'Emails[1]' expected type 'string', got unconvertible type 'int' // * 'Emails[2]' expected type 'string', got unconvertible type 'int' // * 'Name' expected type 'string', got unconvertible type 'int' } func ExampleDecode_metadata() { type Person struct { Name string Age int } // This input can come from anywhere, but typically comes from // something like decoding JSON where we're not quite sure of the // struct initially. input := map[string]interface{}{ "name": "Mitchell", "age": 91, "email": "foo@bar.com", } // For metadata, we make a more advanced DecoderConfig so we can // more finely configure the decoder that is used. In this case, we // just tell the decoder we want to track metadata. var md Metadata var result Person config := &DecoderConfig{ Metadata: &md, Result: &result, } decoder, err := NewDecoder(config) if err != nil { panic(err) } if err := decoder.Decode(input); err != nil { panic(err) } fmt.Printf("Unused keys: %#v", md.Unused) // Output: // Unused keys: []string{"email"} } func ExampleDecode_weaklyTypedInput() { type Person struct { Name string Age int Emails []string } // This input can come from anywhere, but typically comes from // something like decoding JSON, generated by a weakly typed language // such as PHP. input := map[string]interface{}{ "name": 123, // number => string "age": "42", // string => number "emails": map[string]interface{}{}, // empty map => empty array } var result Person config := &DecoderConfig{ WeaklyTypedInput: true, Result: &result, } decoder, err := NewDecoder(config) if err != nil { panic(err) } err = decoder.Decode(input) if err != nil { panic(err) } fmt.Printf("%#v", result) // Output: mapstructure.Person{Name:"123", Age:42, Emails:[]string{}} } func ExampleDecode_tags() { // Note that the mapstructure tags defined in the struct type // can indicate which fields the values are mapped to. type Person struct { Name string `mapstructure:"person_name"` Age int `mapstructure:"person_age"` } input := map[string]interface{}{ "person_name": "Mitchell", "person_age": 91, } var result Person err := Decode(input, &result) if err != nil { panic(err) } fmt.Printf("%#v", result) // Output: // mapstructure.Person{Name:"Mitchell", Age:91} } func ExampleDecode_embeddedStruct() { // Squashing multiple embedded structs is allowed using the squash tag. // This is demonstrated by creating a composite struct of multiple types // and decoding into it. In this case, a person can carry with it both // a Family and a Location, as well as their own FirstName. type Family struct { LastName string } type Location struct { City string } type Person struct { Family `mapstructure:",squash"` Location `mapstructure:",squash"` FirstName string } input := map[string]interface{}{ "FirstName": "Mitchell", "LastName": "Hashimoto", "City": "San Francisco", } var result Person err := Decode(input, &result) if err != nil { panic(err) } fmt.Printf("%s %s, %s", result.FirstName, result.LastName, result.City) // Output: // Mitchell Hashimoto, San Francisco }