Home  >  Article  >  Backend Development  >  How to Parse YAML with Dynamic Keys in Go Using a Custom Unmarshaler?

How to Parse YAML with Dynamic Keys in Go Using a Custom Unmarshaler?

Susan Sarandon
Susan SarandonOriginal
2024-11-04 06:34:01389browse

How to Parse YAML with Dynamic Keys in Go Using a Custom Unmarshaler?

Parsing YAML with Dynamic Key in Go

This problem arises when parsing YAML files with keys that can vary depending on the user's defined API versions. The user may omit or arrange versions as needed (e.g., V0, V2, V5).

Original Approach with Environment Structure

The initial approach involves parsing the YAML as an Environment struct. However, the actual type of the parsed data is map[string]Environment.

<code class="go">type Environment struct {
  SkipHeaderValidation  bool        `yaml:"skip-header-validation"`
  Version               map[string]MajorVersion
}</code>

To resolve this, we need a custom Unmarshaler.

Custom Unmarshaler for Environment

We create a custom Unmarshaler method for the Environment type that parses both the static and dynamic keys.

<code class="go">func (e *Environment) UnmarshalYAML(unmarshal func(interface{}) error) error {
    var params struct {
        SkipHeaderValidation bool `yaml:"skip-header-validation"`
    }
    if err := unmarshal(&amp;params); err != nil {
        return err
    }
    var versions map[string]MajorVersion
    if err := unmarshal(&amp;versions); err != nil {
        // Expect error here due to boolean to MajorVersion conversion
        if _, ok := err.(*yaml.TypeError); !ok {
            return err
        }
    }
    e.SkipHeaderValidation = params.SkipHeaderValidation
    e.Versions = versions
    return nil
}</code>

Modified Parsing and Output

We can now modify our parsing code to handle the dynamic keys and ultimately return the desired data structure.

Modified Main Function

<code class="go">func main() {
    var e map[string]Environment
    if err := yaml.Unmarshal([]byte(data), &amp;e); err != nil {
        fmt.Println(err.Error())
    }
    fmt.Printf("%#v\n", e)
}</code>

Output

The output will now reflect the expected data structure with the dynamic keys parsed accordingly.

map[string]main.Environment{
    "development": {
        SkipHeaderValidation: true,
        Versions:             {
            "V2": {
                Current:                "2.0.0",
                MimeTypes:              {"application/vnd.company.jk.identity+json;", "application/vnd.company.jk.user+json;", "application/vnd.company.jk.role+json;", "application/vnd.company.jk.scope+json;", "application/vnd.company.jk.test+json;"},
                SkipVersionValidation:  false,
                SkipMimeTypeValidation: false,
            },
            "V1": {
                Current:                "1.0.0",
                MimeTypes:              {"application/vnd.company.jk.identity+json;", "application/vnd.company.jk.user+json;", "application/vnd.company.jk.role+json;", "application/vnd.company.jk.scope+json;", "application/vnd.company.jk.test+json;"},
                SkipVersionValidation:  true,
                SkipMimeTypeValidation: true,
            },
        },
    },
}

The above is the detailed content of How to Parse YAML with Dynamic Keys in Go Using a Custom Unmarshaler?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
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