Skip to content

Instantly share code, notes, and snippets.

@Blquinn
Created August 21, 2019 13:49
Show Gist options
  • Save Blquinn/ba605b89dc04268874a00e4d0f46acde to your computer and use it in GitHub Desktop.
Save Blquinn/ba605b89dc04268874a00e4d0f46acde to your computer and use it in GitHub Desktop.
Unmarshaling a dynamic with golang encoding/json
package main
import (
"encoding/json"
"fmt"
)
type Envelope struct {
Type string
Payload interface{}
}
type ReadEnvelope struct {
Type string
Payload json.RawMessage
}
type Person struct {
Name string
}
type Dog struct {
Coat string
}
type Fish struct {
Length float64
}
var typeMap = map[string]func() interface{}{
"person": func() interface{} { return &Person{} },
"dog": func() interface{} { return &Dog{} },
"fish": func() interface{} { return &Fish{} },
}
func main() {
d := []Envelope{
{Type: "person", Payload: Person{Name: "Ben"}},
{Type: "dog", Payload: Dog{Coat: "black"}},
{Type: "fish", Payload: Fish{Length: 20.0}},
{Type: "porgy", Payload: Fish{Length: 20.0}},
}
j, _ := json.Marshal(d)
var lst []ReadEnvelope
json.Unmarshal(j, &lst)
payloads := make([]interface{}, len(lst))
for i, env := range lst {
fn, f := typeMap[env.Type]
if !f {
fmt.Printf("Received unhandled type %s\n", env.Type)
continue
}
v := fn()
json.Unmarshal(env.Payload, v)
payloads[i] = v
}
for _, e := range payloads {
switch v := e.(type) {
case *Person:
fmt.Printf("Got a person and know its type %+v\n", v)
case *Dog:
fmt.Printf("Got a dog and know its type %+v\n", v)
case *Fish:
fmt.Printf("Got a fish and know its type %+v\n", v)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment