Skip to content

Instantly share code, notes, and snippets.

@anonymouse64
Last active March 8, 2019 05:54
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save anonymouse64/bd0321890ce34ba39b92c536bc9080d0 to your computer and use it in GitHub Desktop.
how to unmarshal a custom type in go
package main
import (
"bytes"
"encoding/json"
"fmt"
"log"
"github.com/jinzhu/copier"
)
type theStruct struct {
Thing string
}
// UnmarshalJSON unmarshals the bytes into the struct, performing custom
// error checking on the struct values
func (t *theStruct) UnmarshalJSON(data []byte) error {
fmt.Println("unmarshaling in my custom handler")
type structAlias theStruct
aux := &struct {
*structAlias
}{
structAlias: (*structAlias)(t),
}
err := json.Unmarshal(data, aux)
if err != nil {
return err
}
// perform custom checking on the aux struct
if aux.Thing == "doesn't work" {
return fmt.Errorf("value for Thing is invalid : %s", aux.Thing)
}
// it's all good - put it in the pointer we're working with
// if we wanted we could manually set all the fields or for laziness we
// could just use a library like this :-)
return copier.Copy(t, aux)
}
func main() {
// marshal a dummy struct into the bytes
t := theStruct{
Thing: "doesn't work",
}
data, err := json.Marshal(t)
if err != nil {
log.Println(err)
}
// turn the bytes into an io.Reader and
// try to decode these bytes into the struct
dest := theStruct{}
err = json.NewDecoder(bytes.NewReader(data)).Decode(&dest)
if err != nil {
log.Println(err)
}
// do it again with a struct that passes the validation
src2 := theStruct{
Thing: "works",
}
data2, err := json.Marshal(&src2)
if err != nil {
log.Println(err)
}
dest2 := theStruct{}
err = json.NewDecoder(bytes.NewReader(data2)).Decode(&dest2)
if err != nil {
log.Println(err)
}
fmt.Printf("%+v\n", dest2)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment