UnmarshalYAML does not get called?

Serializing a struct C which has Wrapper struct as field which implements MarshalYAML does not get called.
Is that a bug or what I am doing wrong here?

package ci

import (
	"errors"
	"fmt"
	"testing"

	"github.com/stretchr/testify/require"
	"gopkg.in/yaml.v3"
)

type Interface interface {
	DoUnmarshal(v *yaml.Node) error
}

type Impl struct {
	A string `yaml:"aa"`
}

func (s *Impl) DoUnmarshal(v *yaml.Node) error {
	return v.Decode(&s)
}

type MyType struct {
	Value  bool    `yaml:"v"`
	Custom Wrapper `yaml:"custom"`
}

type Wrapper struct {
	inst Interface
}

var called bool

func (w *Wrapper) MarshalYAML() (interface{}, error) {
	fmt.Printf("Marshal wrapper.")
	called = true
	return w.inst, nil
}

func (w *Wrapper) UnmarshalYAML(v *yaml.Node) error {
	fmt.Printf("Unmarshal wrapper.")
	return w.inst.DoUnmarshal(v)
}

func TestUnmarshal(t *testing.T) {

	c := MyType{
		Value:  true,
		Custom: Wrapper{inst: &Impl{A: "asdf"}}}

	b, e := yaml.Marshal(&c)

	require.NoError(t, e)
	t.Logf("\n%v", string(b))
	require.True(t, called, "MarshalYAML is not called.")
}
type MyType struct {
	Value  bool     `yaml:"v"`
	Custom *Wrapper `yaml:"custom"`
}
func TestUnmarshal(t *testing.T) {

	c := MyType{
		Value:  true,
		Custom: &Wrapper{inst: &Impl{A: "asdf"}},
	}

Adding to what @peakedshout noted: you satisfied the interface for a pointer receiver, not a value receiver. Take a look at this StackOverflow question:

It’s for MarshalJSON but the same idea applies.

1 Like