-- import "."
Package ajson provides a way to marshal and unmarshal JSON with unknown fields.
go get -u go.devnw.com/ajson
func Marshal[T comparable](t T, mm map[string]any) ([]byte, error)
MarshalJSON marshals the given struct to json and then merges the unknown fields into the json from the map[string]any object
Example usage:
type Sample struct {
Name string `json:"name"`
Age int `json:"age"`
Sub *SubSample `json:"sub,omitempty"`
}
type SubSample struct {
Name string `json:"name"`
}
func main() {
sample := Sample{
Name: "John",
Age: 30,
}
unknowns := map[string]any{
"location": "USA",
}
data, err := MarshalJSON(sample, unknowns)
if err != nil {
panic(err)
}
fmt.Println(string(data))
}
// Output:
// {"name":"John","age":30,"location":"USA"}
Example with embeded unknown and custom marshaler:
type Sample struct {
Name string
Age int
Unknowns map[string]any
}
func (s Sample) MarshalJSON() ([]byte, error) {
return MarshalJSON(struct {
ID string `json:"id"`
Name string `json:"name"`
}{
ID: t.ID,
Name: t.Name,
}, t.Unknowns)
}
func Unmarshal[T comparable](data []byte) (T, map[string]any, error)
UnmarshalJSON unmarshals the given json into the given struct and then returns the unknown fields as a map[string]any object.
Example usage:
type Sample struct {
Name string `json:"name"`
Age int `json:"age"`
Sub *SubSample `json:"sub,omitempty"`
}
type SubSample struct {
Name string `json:"name"`
}
func main() {
data := []byte(`{"name":"John","age":30,"location":"USA"}`)
var sample Sample
unknowns, err := UnmarshalJSON(data, &sample)
if err != nil {
panic(err)
}
fmt.Println(sample)
fmt.Println(unknowns)
}
// Output:
// {John 30 &{ }}
// map[location:USA]
Example with embeded unknown and custom unmarshaler:
type Sample struct {
Name string
Age int
Unknowns map[string]any
}
func (s *Sample) UnmarshalJSON(data []byte) error {
var t struct {
ID string `json:"id"`
Name string `json:"name"`
}
unknowns, err := UnmarshalJSON(data, &t)
if err != nil {
return err
}
s.Name = t.Name
s.Age = t.Age
s.Unknowns = unknowns
return nil
}