Skip to content

Instantly share code, notes, and snippets.

@lxfontes
Created April 16, 2019 18:52
Show Gist options
  • Save lxfontes/261523970a4ec9c9ed81c8fa0467b5ac to your computer and use it in GitHub Desktop.
Save lxfontes/261523970a4ec9c9ed81c8fa0467b5ac to your computer and use it in GitHub Desktop.
package main
import (
"encoding/json"
"fmt"
)
type Thing1 struct {
String string `json:"meow"`
}
func (Thing1) DoThing() {}
type Thing2 struct {
Number int `json:"number"`
String string `json:"string"`
}
func (Thing2) DoThing() {}
type Bleh interface {
DoThing()
}
type Holder struct {
Type string `json:"type"`
Doer Bleh
}
func (h *Holder) UnmarshalJSON(data []byte) error {
type HolderPayload Holder
aux := &struct {
Payload json.RawMessage `json:"payload"`
*HolderPayload
}{
HolderPayload: (*HolderPayload)(h),
}
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
knownTypes := map[string]Bleh{
"Thing1": &Thing1{},
"Thing2": &Thing2{},
}
t, ok := knownTypes[aux.Type]
if !ok {
return fmt.Errorf("unknown type: %s", aux.Type)
}
if err := json.Unmarshal(aux.Payload, t); err != nil {
return err
}
h.Doer = t
return nil
}
func thing1() {
payload := `{
"type": "Thing2",
"payload": {
"number": 42,
"string": "once upon a time in a galaxy far far away"
}
}`
h := &Holder{}
if err := json.Unmarshal([]byte(payload), h); err != nil {
fmt.Println(err)
}
fmt.Println(h)
fmt.Println(h.Doer)
}
func thing2() {
payload := `{
"type": "Thing1",
"payload": {
"meow": "lols"
}
}`
h := &Holder{}
if err := json.Unmarshal([]byte(payload), h); err != nil {
fmt.Println(err)
}
fmt.Println(h)
fmt.Println(h.Doer)
}
func main() {
thing1()
thing2()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment