Skip to content

Instantly share code, notes, and snippets.

@jordanorelli
Created June 4, 2012 19:00
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jordanorelli/2870187 to your computer and use it in GitHub Desktop.
Save jordanorelli/2870187 to your computer and use it in GitHub Desktop.
multi-stage json decoding in Go
package main
import (
"encoding/json"
"fmt"
"strings"
)
var (
stream = `
{
"type": "human",
"name": "jordan",
"city": "new york"
}
{
"type": "dog",
"name": "kiba",
"breed": "husky"
}
`
jsonconfig = map[string]func() JSONHandler{
"human": func() JSONHandler { return new(Human) },
"dog": func() JSONHandler { return new(Dog) },
}
)
type JSONHandler interface {
HandleJSON([]byte) error
}
type Mask struct {
TypeName string `json:"type"`
}
type Human struct {
Name string `json:"name"`
City string `json:"city"`
}
func (h *Human) HandleJSON(raw []byte) error {
if err := json.Unmarshal(raw, h); err != nil {
return err
}
fmt.Println(h)
return nil
}
type Dog struct {
Name string `json:"name"`
Breed string `json:"breed"`
}
func (d *Dog) HandleJSON(raw []byte) error {
if err := json.Unmarshal(raw, d); err != nil {
return err
}
fmt.Println(d)
return nil
}
func main() {
e := json.NewDecoder(strings.NewReader(stream))
for {
var raw json.RawMessage
if err := e.Decode(&raw); err != nil {
break
}
var m Mask
if err := json.Unmarshal(raw, &m); err != nil {
break
}
if err := jsonconfig[m.TypeName]().HandleJSON([]byte(raw)); err != nil {
break
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment