@@ -2,6 +2,9 @@ package mapstructure
2
2
3
3
import (
4
4
"fmt"
5
+ "reflect"
6
+ "strconv"
7
+ "strings"
5
8
)
6
9
7
10
func ExampleDecode () {
@@ -289,3 +292,68 @@ func ExampleDecode_omitempty() {
289
292
// Output:
290
293
// &map[Age:0 FirstName:Somebody]
291
294
}
295
+
296
+ func ExampleDecode_decodeHookFunc () {
297
+ type PersonLocation struct {
298
+ Latitude float64
299
+ Longtitude float64
300
+ }
301
+
302
+ type Person struct {
303
+ Name string
304
+ Location PersonLocation
305
+ }
306
+
307
+ // Example of parsing messy input: here we have latitude, longitude squashed into
308
+ // a single string field. We write a custom DecodeHookFunc to parse the '#' separated
309
+ // values into a PersonLocation struct.
310
+ input := map [string ]interface {}{
311
+ "name" : "Mitchell" ,
312
+ "location" : "-35.2809#149.1300" ,
313
+ }
314
+
315
+ toPersonLocationHookFunc := func () DecodeHookFunc {
316
+ return func (f reflect.Type , t reflect.Type , data interface {}) (interface {}, error ) {
317
+ if t != reflect .TypeOf (PersonLocation {}) {
318
+ return data , nil
319
+ }
320
+
321
+ switch f .Kind () {
322
+ case reflect .String :
323
+ xs := strings .Split (data .(string ), "#" )
324
+
325
+ if len (xs ) == 2 {
326
+ lat , errLat := strconv .ParseFloat (xs [0 ], 64 )
327
+ lon , errLon := strconv .ParseFloat (xs [1 ], 64 )
328
+
329
+ if errLat == nil && errLon == nil {
330
+ return PersonLocation {Latitude : lat , Longtitude : lon }, nil
331
+ }
332
+ } else {
333
+ return data , nil
334
+ }
335
+ }
336
+ return data , nil
337
+ }
338
+ }
339
+
340
+ var result Person
341
+
342
+ decoder , errDecoder := NewDecoder (& DecoderConfig {
343
+ Metadata : nil ,
344
+ DecodeHook : toPersonLocationHookFunc (), // Here, use ComposeDecodeHookFunc to run multiple hooks.
345
+ Result : & result ,
346
+ })
347
+ if errDecoder != nil {
348
+ panic (errDecoder )
349
+ }
350
+
351
+ err := decoder .Decode (input )
352
+ if err != nil {
353
+ panic (err )
354
+ }
355
+
356
+ fmt .Printf ("%#v" , result )
357
+ // Output:
358
+ // mapstructure.Person{Name:"Mitchell", Location:mapstructure.PersonLocation{Latitude:-35.2809, Longtitude:149.13}}
359
+ }
0 commit comments