My question is very similar to this one, however instead of converting a float64
to a string
which is handled using the string tag. In my case I'm trying to convert a ObjectID
to a string using it's .Hex()
method. And, vice versa using the .FromHex()
function on the way back.
However, more generically how do I convert from type X
to type Y
& back during the Marshal
& Unmarshal
ing?
My Example:
package main
import (
"log"
"fmt"
"encoding/json"
"github.com/mongodb/mongo-go-driver/bson/objectid"
)
type Greeting struct {
Id *objectid.ObjectID `json:"id"`
Greeting string `json:"greeting,omitempty"`
}
func main() {
// Create ObjectID
id, err := objectid.FromHex("5b14dd20f6418c8443a5ffec")
if err != nil { log.Fatal(err) }
// Create Greeting
g := Greeting{&id, "Hello, World!"}
// Marshal to json
j, err := json.Marshal(g)
if err != nil { log.Fatal(err) }
// Print Json
fmt.Printf("Json: %s", string(j))
}
Output:
Json: {"id":[91,20,221,32,246,65,140,132,67,165,255,236],"greeting":"Hello, World!"}
Whereas, what I'd like is:
Json: {"id":"5b14dd20f6418c8443a5ffec","greeting":"Hello, World!"}
You should write your own (un)marshalling function in which you process your conversions/conditions and handle it as argument in calling the json (un)marshalling.
type Whatever struct {
someField int
}
func (w Whatever) MarshalJSON() ([]byte, error) {
return json.Marshal(struct{
SomeField int `json:"some_field"`
}{
SomeField: w.someField,
})
}
func (w Whatever) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
"some_field": w.SomeField,
})
}