How Can I Dynamically Parse a YAML Field to Specific Structs in Go?

Susan Sarandon
Release: 2024-10-31 03:50:01
Original
691 people have browsed it

How Can I Dynamically Parse a YAML Field to Specific Structs in Go?

Dynamically Parse YAML Field to Predefined Structs in Go

For a YAML file where a particular field can be represented by any value from a predetermined set of structs, a suitable approach would be to utilize the YAML package's UnmarshalYAML method. This allows for the creation of custom unmarshaling logic for specific types.

YAML v2

Using YAML v2, the following code achieves the desired behavior:

<code class="go">type yamlNode struct {
    unmarshal func(interface{}) error
}

func (n *yamlNode) UnmarshalYAML(unmarshal func(interface{}) error) error {
    n.unmarshal = unmarshal
    return nil
}

type Spec struct {
    Kind string      `yaml:"kind"`
    Spec interface{} `yaml:"-"`
}</code>
Copy after login
<code class="go">func (s *Spec) UnmarshalYAML(unmarshal func(interface{}) error) error {
    type S Spec
    type T struct {
        S    `yaml:",inline"`
        Spec yamlNode `yaml:"spec"`
    }

    obj := &T{}
    if err := unmarshal(obj); err != nil {
        return err
    }
    *s = Spec(obj.S)

    switch s.Kind {
    case "foo":
        s.Spec = new(Foo)
    case "bar":
        s.Spec = new(Bar)
    default:
        panic("kind unknown")
    }
    return obj.Spec.unmarshal(s.Spec)
}</code>
Copy after login

YAML v3

For YAML v3, use the following code:

<code class="go">type Spec struct {
    Kind string      `yaml:"kind"`
    Spec interface{} `yaml:"-"`
}</code>
Copy after login
<code class="go">func (s *Spec) UnmarshalYAML(n *yaml.Node) error {
    type S Spec
    type T struct {
        *S   `yaml:",inline"`
        Spec yaml.Node `yaml:"spec"`
    }

    obj := &T{S: (*S)(s)}
    if err := n.Decode(obj); err != nil {
        return err
    }

    switch s.Kind {
    case "foo":
        s.Spec = new(Foo)
    case "bar":
        s.Spec = new(Bar)
    default:
        panic("kind unknown")
    }
    return obj.Spec.Decode(s.Spec)
}</code>
Copy after login

This approach provides a simple and elegant way to unmarshal YAML data into a predefined set of structs while avoiding additional parsing steps or excessive memory consumption.

The above is the detailed content of How Can I Dynamically Parse a YAML Field to Specific Structs in Go?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!