Description
Proposal Details
As recommended by Joe Tsai (go-json-experiment/json#168), I am opening this proposal.
The current v2 JSON API allows for customized generic marshalers and unmarshalers, such as:
// MarshalFunc constructs a type-specific marshaler that
// specifies how to marshal values of type T.
func MarshalFunc[T any](fn func(T) ([]byte, error)) *Marshalers
I attempted to adapt my enum package package to the new v2 API in order to support interface-based marshalling and unmarshalling using various styles (e.g., internally or externally tagged). However, I encountered a limitation: the current API only supports generic type parameters for defining custom marshalers and unmarshalers. Since my implementation relies on dynamic type discovery via reflect.Type, I cannot instantiate the required generic types.
To address this, I propose extending the API with additional functions that accept reflect.Type, for example:
// MarshalFuncOf constructs a type-specific marshaler that
// specifies how to marshal values of the given reflect.Type.
func MarshalFuncOf(t reflect.Type, fn func(reflect.Type) ([]byte, error)) *Marshalers
// UnmarshalFuncOf constructs a type-specific unmarshaler that
// specifies how to unmarshal values of the given reflect.Type.
func UnmarshalFuncOf(t reflect.Type, fn func([]byte, reflect.Type) error) *Unmarshalers
This approach would be consistent with how the reflect package provides both TypeOf(any) and TypeFor[T], enabling both static and dynamic use cases.
Alternatively, or in addition, I would also welcome native support in the v2 package for interface-based marshalling and unmarshalling, which would significantly improve flexibility for libraries relying on dynamic types.