1package mapstructure 2 3import ( 4 "fmt" 5) 6 7func ExampleDecode() { 8 type Person struct { 9 Name string 10 Age int 11 Emails []string 12 Extra map[string]string 13 } 14 15 // This input can come from anywhere, but typically comes from 16 // something like decoding JSON where we're not quite sure of the 17 // struct initially. 18 input := map[string]interface{}{ 19 "name": "Mitchell", 20 "age": 91, 21 "emails": []string{"one", "two", "three"}, 22 "extra": map[string]string{ 23 "twitter": "mitchellh", 24 }, 25 } 26 27 var result Person 28 err := Decode(input, &result) 29 if err != nil { 30 panic(err) 31 } 32 33 fmt.Printf("%#v", result) 34 // Output: 35 // mapstructure.Person{Name:"Mitchell", Age:91, Emails:[]string{"one", "two", "three"}, Extra:map[string]string{"twitter":"mitchellh"}} 36} 37 38func ExampleDecode_errors() { 39 type Person struct { 40 Name string 41 Age int 42 Emails []string 43 Extra map[string]string 44 } 45 46 // This input can come from anywhere, but typically comes from 47 // something like decoding JSON where we're not quite sure of the 48 // struct initially. 49 input := map[string]interface{}{ 50 "name": 123, 51 "age": "bad value", 52 "emails": []int{1, 2, 3}, 53 } 54 55 var result Person 56 err := Decode(input, &result) 57 if err == nil { 58 panic("should have an error") 59 } 60 61 fmt.Println(err.Error()) 62 // Output: 63 // 5 error(s) decoding: 64 // 65 // * 'Age' expected type 'int', got unconvertible type 'string', value: 'bad value' 66 // * 'Emails[0]' expected type 'string', got unconvertible type 'int', value: '1' 67 // * 'Emails[1]' expected type 'string', got unconvertible type 'int', value: '2' 68 // * 'Emails[2]' expected type 'string', got unconvertible type 'int', value: '3' 69 // * 'Name' expected type 'string', got unconvertible type 'int', value: '123' 70} 71 72func ExampleDecode_metadata() { 73 type Person struct { 74 Name string 75 Age int 76 } 77 78 // This input can come from anywhere, but typically comes from 79 // something like decoding JSON where we're not quite sure of the 80 // struct initially. 81 input := map[string]interface{}{ 82 "name": "Mitchell", 83 "age": 91, 84 "email": "foo@bar.com", 85 } 86 87 // For metadata, we make a more advanced DecoderConfig so we can 88 // more finely configure the decoder that is used. In this case, we 89 // just tell the decoder we want to track metadata. 90 var md Metadata 91 var result Person 92 config := &DecoderConfig{ 93 Metadata: &md, 94 Result: &result, 95 } 96 97 decoder, err := NewDecoder(config) 98 if err != nil { 99 panic(err) 100 } 101 102 if err := decoder.Decode(input); err != nil { 103 panic(err) 104 } 105 106 fmt.Printf("Unused keys: %#v", md.Unused) 107 // Output: 108 // Unused keys: []string{"email"} 109} 110 111func ExampleDecode_weaklyTypedInput() { 112 type Person struct { 113 Name string 114 Age int 115 Emails []string 116 } 117 118 // This input can come from anywhere, but typically comes from 119 // something like decoding JSON, generated by a weakly typed language 120 // such as PHP. 121 input := map[string]interface{}{ 122 "name": 123, // number => string 123 "age": "42", // string => number 124 "emails": map[string]interface{}{}, // empty map => empty array 125 } 126 127 var result Person 128 config := &DecoderConfig{ 129 WeaklyTypedInput: true, 130 Result: &result, 131 } 132 133 decoder, err := NewDecoder(config) 134 if err != nil { 135 panic(err) 136 } 137 138 err = decoder.Decode(input) 139 if err != nil { 140 panic(err) 141 } 142 143 fmt.Printf("%#v", result) 144 // Output: mapstructure.Person{Name:"123", Age:42, Emails:[]string{}} 145} 146 147func ExampleDecode_tags() { 148 // Note that the mapstructure tags defined in the struct type 149 // can indicate which fields the values are mapped to. 150 type Person struct { 151 Name string `mapstructure:"person_name"` 152 Age int `mapstructure:"person_age"` 153 } 154 155 input := map[string]interface{}{ 156 "person_name": "Mitchell", 157 "person_age": 91, 158 } 159 160 var result Person 161 err := Decode(input, &result) 162 if err != nil { 163 panic(err) 164 } 165 166 fmt.Printf("%#v", result) 167 // Output: 168 // mapstructure.Person{Name:"Mitchell", Age:91} 169} 170 171func ExampleDecode_embeddedStruct() { 172 // Squashing multiple embedded structs is allowed using the squash tag. 173 // This is demonstrated by creating a composite struct of multiple types 174 // and decoding into it. In this case, a person can carry with it both 175 // a Family and a Location, as well as their own FirstName. 176 type Family struct { 177 LastName string 178 } 179 type Location struct { 180 City string 181 } 182 type Person struct { 183 Family `mapstructure:",squash"` 184 Location `mapstructure:",squash"` 185 FirstName string 186 } 187 188 input := map[string]interface{}{ 189 "FirstName": "Mitchell", 190 "LastName": "Hashimoto", 191 "City": "San Francisco", 192 } 193 194 var result Person 195 err := Decode(input, &result) 196 if err != nil { 197 panic(err) 198 } 199 200 fmt.Printf("%s %s, %s", result.FirstName, result.LastName, result.City) 201 // Output: 202 // Mitchell Hashimoto, San Francisco 203} 204 205func ExampleDecode_remainingData() { 206 // Note that the mapstructure tags defined in the struct type 207 // can indicate which fields the values are mapped to. 208 type Person struct { 209 Name string 210 Age int 211 Other map[string]interface{} `mapstructure:",remain"` 212 } 213 214 input := map[string]interface{}{ 215 "name": "Mitchell", 216 "age": 91, 217 "email": "mitchell@example.com", 218 } 219 220 var result Person 221 err := Decode(input, &result) 222 if err != nil { 223 panic(err) 224 } 225 226 fmt.Printf("%#v", result) 227 // Output: 228 // mapstructure.Person{Name:"Mitchell", Age:91, Other:map[string]interface {}{"email":"mitchell@example.com"}} 229} 230 231func ExampleDecode_omitempty() { 232 // Add omitempty annotation to avoid map keys for empty values 233 type Family struct { 234 LastName string 235 } 236 type Location struct { 237 City string 238 } 239 type Person struct { 240 *Family `mapstructure:",omitempty"` 241 *Location `mapstructure:",omitempty"` 242 Age int 243 FirstName string 244 } 245 246 result := &map[string]interface{}{} 247 input := Person{FirstName: "Somebody"} 248 err := Decode(input, &result) 249 if err != nil { 250 panic(err) 251 } 252 253 fmt.Printf("%+v", result) 254 // Output: 255 // &map[Age:0 FirstName:Somebody] 256} 257