#639·yaml

v3: Feature Request: Decoder/Encoder Options

Author: abursavichCreated Jul 31, 2020Updated Feb 12, 2025

I was trying to upgrade a project from v2 to v3 and found liberal uses of yaml.UmarshalStrict which is no longer available in v3. I assume the removal of that function was a conscious decision and UnmarshalStrict is being avoided along with MarshalIndent.

Instead of having to wrap the bytes with a bytes.Reader, create a Decoder, call dec.KnownFields(true), then Decode, I think it would be more ergonomic to have options for Marshal/Unmarshal and/or NewDecoder/NewEncoder.

go
type DecoderOption func(*Decoder)

func KnownFields(enable bool) DecoderOption {
    return func(d *Decoder) { d.KnownFields(enable) }
}

func NewDecoder(r io.Reader, options ...DecoderOption) *Decoder { /* ... */ }

func Unmarshal(in []byte, out interface{}, options ...DecoderOption) error { /* ... */ }

type EncoderOption func(*Encoder)

func SetIndent(spaces int) EncoderOption {
    return func(e *Encoder) { e.SetIndent(spaces) }
}

func NewEncoder(w io.Writer, options ...EncoderOption) *Encoder { /* ... */ }

func Marshal(in interface{}, options ...EncoderOption) ([]byte, error) { /* ... */ }

This would allow:

go
if err := yaml.Unmarshal(b, &out, yaml.KnownFields(true)); err != nil { /* ... */ }
// or
if err := yaml.NewDecoder(r, yaml.KnownFields(true)).Decode(&out); err != nil { /* ... */ }

Similar for Marshal and SetIndent.

Or just add UnmarshalStrict and MarshalIndent functions :)