@@ -2,6 +2,9 @@ package mapstructure
22
33import (
44 "fmt"
5+ "reflect"
6+ "strconv"
7+ "strings"
58)
69
710func ExampleDecode () {
@@ -289,3 +292,68 @@ func ExampleDecode_omitempty() {
289292 // Output:
290293 // &map[Age:0 FirstName:Somebody]
291294}
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