ugorji / go

idiomatic codec and rpc lib for msgpack, cbor, json, etc. msgpack.org[Go]
MIT License
1.86k stars 295 forks source link

Custom MarshalJSON and UnmarshalJSON methods for structs with custom data types #359

Closed ls-sacchit-chadha closed 3 years ago

ls-sacchit-chadha commented 3 years ago

Hi, I am wondering if the codecgen tool can be used for for generating custom MarshalJSON and UnmarshalJSON methods for structs with fields having custom data types for e.g.

type Foo struct {
 ID   string  `json:"id"`
 Name string  `json:"name"`
}

type FooBar struct {
 FooPtr *Foo
}

func (strct *FooBar) MarshalJSON() ([]byte, error) {
 // Implementation
}

func (strct *FooBar) UnmarshalJSON(b []byte) error {
 // Implementation
}

func (strct *Foo) MarshalJSON() ([]byte, error) {
 // Implementation
}

func (strct *Foo) UnmarshalJSON(b []byte) error {
 // Implementation
}

var f FooBar
// assuming f is populated with data

// usage
f.MarshalJSON()
f.UnmarshalJSON()

thank you!

ugorji commented 3 years ago

Unfortunately, no.

This will introduce an infinite loop, as codecgen tool will delegate to MarshalJSON/UnmarshalJSON methods if they exist on a given type and we are doing a json encode or decode. Consequently, if CodecEncodeSelf calls MarshalJSON which calls CodecEncodeSelf which calls MarshalJSON which calls ... (infinite loop).

Do not let them depend on each other. UnmarshalJSON is for types that can handle json encode/decode themselves. CodecEncodeSelf can handle encoding/decoding for any format, and is smart enough to delegate to UnmarshalJSON, etc if doing a json decode for example.