How to Dynamically Parse a YAML Field into a Finite Set of Structs in Go?

Barbara Streisand
Release: 2024-10-30 23:11:30
Original
288 people have browsed it

How to Dynamically Parse a YAML Field into a Finite Set of Structs in Go?

Dynamically Parse YAML Field to a Finite Set of Structs in Go

Introduction

Parsing YAML into a struct in Go can be straightforward. However, when a YAML field can represent multiple possible structs, the task becomes more complex. This article explores a dynamic approach using Go's YAML package.

Dynamic Unmarshaling with YAML v2

For Yaml v2, the following approach can be used:

<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

Dynamic Unmarshaling with YAML v3

For Yaml v3, the approach is slightly different:

<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

Conclusion

These dynamic unmarshaling techniques allow for flexible parsing of YAML fields into a finite set of structs, providing a more elegant and efficient solution than the proposed workaround. Feel free to explore the provided code snippets and optimize the approach based on your specific requirements.

The above is the detailed content of How to Dynamically Parse a YAML Field into a Finite Set of 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