Skip to content

proposal: encoding/json/v2: MarshalFunc with reflect.Type #73457

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
torbenschinke opened this issue Apr 21, 2025 · 1 comment
Open

proposal: encoding/json/v2: MarshalFunc with reflect.Type #73457

torbenschinke opened this issue Apr 21, 2025 · 1 comment
Labels
LibraryProposal Issues describing a requested change to the Go standard library or x/ libraries, but not to a tool Proposal
Milestone

Comments

@torbenschinke
Copy link
Contributor

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.

@gabyhelp
Copy link

Related Issues

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)

@gabyhelp gabyhelp added the LibraryProposal Issues describing a requested change to the Go standard library or x/ libraries, but not to a tool label Apr 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
LibraryProposal Issues describing a requested change to the Go standard library or x/ libraries, but not to a tool Proposal
Projects
None yet
Development

No branches or pull requests

3 participants