Skip to content
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

v3: yaml.Unmarshaler.UnmarshalYAML does not get called on inlined maps #742

Open
lithdew opened this issue May 29, 2021 · 4 comments
Open

Comments

@lithdew
Copy link

lithdew commented May 29, 2021

Having the receiver of UnmarshalYAML be a pointer receiver does not seem to change the fact that "this does not get called" does not get printed.

package main

import (
	"fmt"
	"gopkg.in/yaml.v3"
)

type Field struct {
	Properties Properties `yaml:"-,inline"`
}

var _ yaml.Unmarshaler = Properties{}

type Properties map[string]string

func (p Properties) UnmarshalYAML(value *yaml.Node) error {
	fmt.Println("this does not get called")
	return value.Decode(p)
}

func main() {
	input := `a: 1
b: 2
c: 3`

	var field Field
	if err := yaml.Unmarshal([]byte(input), &field); err != nil {
		panic(err)
	}

	fmt.Println(field)
}
@sustrik
Copy link

sustrik commented May 30, 2021

I wonder whether this is a more generic problem about structs without custom (un)marshaller not calling custome (un)marshaller on the struct members:


import (
    "fmt"
    "log"
    "gopkg.in/yaml.v3"
)

type Outer struct {
  Inner Inner
}

type Inner struct {}

func (i *Inner) MarshalYAML() (interface{}, error) {
	return "foo", nil
}

func main() {
    t := Outer{}
    data, err := yaml.Marshal(t)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%s\n", data)
}

Expected: "inner: foo" Got: "inner: {}"

@sustrik
Copy link

sustrik commented May 30, 2021

After a bit of debugging: In my case the problem can be fixed by making Inner a pointer:

type Outer struct {
  Inner *Inner
}

The problem is caused by marshal() function trying to convert the value to Marshaller interface, but of course, given that the structure is embedded, rather than referred to by a pointer, the conversion fails. (see

yaml/encode.go

Line 125 in 7649d45

case Marshaler:
)

I wonder whether a special case can be added, that makes pointer to the structure and tries to convert that to Marshaller.

@sustrik
Copy link

sustrik commented May 30, 2021

Tentative PR: #743

@aathan
Copy link

aathan commented Aug 9, 2023

#979

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants