go-yaml / yaml

YAML support for the Go language.
Other
6.77k stars 1.03k forks source link

Add support for Go Composition #517

Closed mmilley closed 4 years ago

mmilley commented 4 years ago

In the example below, unmarshaling the data into Child will not hydrate MyBaseField; in Go, this would be expected behavior, and is supported by the JSON encoder.

type Base struct { MyBaseField string yaml:"myBaseField,omitempty" }

type Child struct{ Base MyChildField string yaml:"myChildField,omitempty" }

---------- YAML data below:

myBaseField: test1 myChildField: test2

Current result: myChild.MyBaseField=="" myChild.MyChildField=="test2"

Expected result: myChild.MyBaseField=="test1" myChild.MyBaseField=="test2"

niemeyer commented 4 years ago

Inlining in the yaml package is supported independently of how your Go code is organized, via the inline tag:

https://gopkg.in/yaml.v3#Marshal

mmilley commented 4 years ago

Adding the inline tag does not solve this issue.

I'll create something in Go Playground to illustrate this better.

mmilley commented 4 years ago

https://play.golang.org/p/99jkRILRg-W

Do you want me to open a new ticket, or...?


package main

import (
    "encoding/json"
    "fmt"
    "gopkg.in/yaml.v2"
)

type Person struct {
    Name string `json:"name,omitempty" yaml:"name,omitempty,inline"`
}

type Physician struct {
    Person
    Credentials string `json:"credentials,omitempty" yaml:"credentials,omitempty"`
}

func main() {
    yamlData := "name: Dr. Chuck Norris\ncredentials: Black Belt"
    jsonData := `{"name":"Dr. Chuck Norris", "credentials":"Black Belt"}`

    var yamlDoc Physician
    var jsonDoc Physician

    yaml.Unmarshal(([]byte)(yamlData), &yamlDoc)
    json.Unmarshal(([]byte)(jsonData), &jsonDoc)

    fmt.Println("JSON Version")
    fmt.Printf("Name: %v ; Credentials: %v", jsonDoc.Name, jsonDoc.Credentials)

    fmt.Println("\n\nYAML Version")
    fmt.Printf("Name: %v ; Credentials: %v", yamlDoc.Name, yamlDoc.Credentials)
}
niemeyer commented 4 years ago

Your goal is to inline the person into the physician, not the name into the person. The tag is misplaced.

mmilley commented 4 years ago

I don't want the yaml structure to be

person: 
   name: Dr. Chuck Norris
credentials: Black Belt

Can provide an example that works? I'm not seeing the path forward here.

mmilley commented 4 years ago

Nevermind, I think I see it.

mmilley commented 4 years ago

Yep, that resolved it.

Thank you for your time. 👍🏻

For others: https://play.golang.org/p/XK6IRjHT_nX