go-viper / mapstructure

Go library for decoding generic map values into native Go structures and vice versa.
MIT License
139 stars 13 forks source link

How to customize the values mapped to the map? #35

Open baagod opened 2 months ago

baagod commented 2 months ago
package main

import (
    "fmt"
    "reflect"
    "time"

    "github.com/go-viper/mapstructure/v2"
)

type Person struct {
    Time time.Time `json:"time"`
    Name string    `json:"name"`
}

func main() {
    result := map[string]any{}
    input := Person{time.Now(), "testName"}

    decoder, errDecoder := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
        DecodeHook: func(f reflect.Type, t reflect.Type, data any) (any, error) {
            if value, ok := data.(*time.Time); ok {
                return value.Format(time.DateTime), nil
            }
            return data, nil
        },
        Result:  &result,
        TagName: "json",
    })

    if errDecoder != nil {
        panic(errDecoder)
    }

    err := decoder.Decode(input)
    if err != nil {
        panic(err)
    }

    fmt.Printf("%#v\n", result)
}

Here, I want to add the 'time' of the structure Convert the Time type to a string in the 'result', but it cannot be done. report errors:

panic: 'time' expected a map, got 'string'

goroutine 1 [running]:
main.main()
    C:/Users/78081/AppData/Roaming/JetBrains/GoLand2024.1/scratches/scratch.go:37 +0x1a6

Is there a solution?

MrDan4es commented 1 month ago

Same question here https://stackoverflow.com/questions/78937099/go-encode-struct-to-mapstringany-with-mapstructure-decodehookfunc

baagod commented 1 month ago

@MrDan4es I pulled a request #43, not sure if it can be merged, I'm currently using my own fork of the: go get github.com/baagod/mapstructure/v2@b1