Handle json.RawMessage or introduce a similar type
nieomylnieja opened this issue · comments
Is your feature request related to a problem? Please describe.
When decoding models that support both JSON and YAML encoding, it's convenient that we already support json
tags for YAML, but when using json.RawMessage
go-yaml
does not handle it.
Due to that there's no native (from go-yaml
perspective) way to handle such models.
Converting from YAML to JSON is not an option for me as I want to retain separate syntax errors for JSON and YAML.
Describe the solution you'd like
We should either handle json.RawMessage
type or introduce a new type, like yaml.RawMessage
which could implement both json.(Un)marshaler
and yaml.Bytes(Un)marshaler
interfaces.
Describe alternatives you've considered
Currently I've implemented my own type for that.
Having to redefine it in every project I work with though is not ideal.
package serdeutil
import "github.com/pkg/errors"
// RawMessage is a raw encoded JSON or YAML value.
// It implements:
// - [json.Marshaler] and [json.Unmarshaler]
// - [yaml.BytesMarshaler] and [yaml.BytesUnmarshaler]
// It can be used to delay JSON/YAML decoding or precompute a JSON/YAML encoding.
type RawMessage []byte
func (m RawMessage) MarshalJSON() ([]byte, error) { return m.marshal() }
func (m RawMessage) MarshalYAML() ([]byte, error) { return m.marshal() }
func (m RawMessage) marshal() ([]byte, error) {
if m == nil {
return []byte("null"), nil
}
return m, nil
}
func (m *RawMessage) UnmarshalJSON(data []byte) error { return m.unmarshal(data) }
func (m *RawMessage) UnmarshalYAML(data []byte) error { return m.unmarshal(data) }
func (m *RawMessage) unmarshal(data []byte) error {
if m == nil {
return errors.New("RawMessage: unmarshal on nil pointer")
}
*m = append((*m)[0:0], data...)
return nil
}