pjson

Help to easily JSON marshal / unmarshal tagged unions in go
A tagged union / discriminating type is, for instance with the following JSON:
[
{ "type": "a", "a_name": "AName", "a_foo": "FOO" },
{ "type": "b", "b_name": "BName", "b_goo": "GOO" }
]
The type
field denotes which type the object is. So many object share a common discriminating field.
In some languages this is supported, but not in go.
Pjson gives us a helper pjson.Tagged
type to create these pseudo tagged unions that can be automatically serialized and deserialized to and from JSON.
Usage
package readme
import (
"encoding/json"
"fmt"
"reflect"
"github.com/byrnedo/pjson"
)
type Foo struct {
A string `json:"a"`
}
// set it's tag value
func (a Foo) Variant() string {
return "foo"
}
type Bar struct {
B string `json:"b"`
}
func (b Bar) Variant() string {
return "bar"
}
// specify the union
type FooBarUnion struct{}
func (u FooBarUnion) Field() string { return "type" }
func (u FooBarUnion) Variants() []pjson.Variant {
return []pjson.Variant{
Foo{}, Bar{},
}
}
func ExampleReadme() {
// now that we have our types we can use OneOf
o := pjson.Tagged[FooBarUnion]{}
bytes := []byte(`{"type": "foo", "a": "AAAA"}`)
err := json.Unmarshal(bytes, &o)
if err != nil {
panic(err)
}
fmt.Println(reflect.TypeOf(o.Value), o.Value)
bytes, _ = json.Marshal(o)
fmt.Println(string(bytes))
// Output: *pjson_test.Foo &{AAAA}
// {"a":"AAAA","type":"foo"}
}