Skip to content

Commit

Permalink
fix: Marshaler interface works with pointers and values
Browse files Browse the repository at this point in the history
  • Loading branch information
masonkatz committed Aug 24, 2023
1 parent f6f7691 commit adc6764
Showing 1 changed file with 23 additions and 1 deletion.
24 changes: 23 additions & 1 deletion encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,33 @@ func (e *encoder) marshalDoc(tag string, in reflect.Value) {
}

func (e *encoder) marshal(tag string, in reflect.Value) {
tag = shortTag(tag)
if !in.IsValid() || in.Kind() == reflect.Ptr && in.IsNil() {
e.nilv()
return
}

// Inspired by json/encode.go newTypeEncoder:
//
// If we have a non-pointer value whose type implements Marshaler with a
// value receiver, then we're better off taking the address of the value -
// otherwise we end up with an allocation as we cast the value to an
// interface.

// This also means that when starting with a non-pointer value as the root
// of the document we will try the pointer value to see of the Marshaler
// interface is implemented.
//
// Fixes: https://github.com/go-yaml/yaml/issues/714

if in.Kind() != reflect.Pointer && in.CanAddr() {
p := in.Addr()
if _, ok := p.Interface().(Marshaler); ok {
in = p // marshal in as a pointer
}
}

tag = shortTag(tag)

iface := in.Interface()
switch value := iface.(type) {
case *Node:
Expand Down

0 comments on commit adc6764

Please sign in to comment.