YAML Unmarshal map[string]struct

Viewed 5583

I am definitely not getting this. Here is a given yaml file

items:
  - item1:
      one: "some"
      two: "some string"
  - item2:
      one: "some"
      two: "some string"

And a config:

type Item struct {
    one string
    two string
}
type conf struct {
    Items map[string]Item
}

func (c *conf) getConfig(filename string) *conf {

    yamlFile, err := ioutil.ReadFile(filename)
    if err != nil {
        log.Printf("yamlFile.Get err   #%v ", err)
    }
    err = yaml.Unmarshal(yamlFile, &c)
    if err != nil {
        log.Fatalf("Unmarshal: %v", err)
    }

    //c.Items = make(map[string]Items)
    return c
}

I am using gopkg.in/yaml.v2

With this error:

Unmarshal: yaml: unmarshal errors:
  line 6: cannot unmarshal !!seq into map[string]application.Item

Please help me understand what I am doing wrong here. I googled everywhere already. Thanks in advance.

3 Answers

First, you need to change your YAML to

  items:
      item1:
        one: "some"
        two: "some string"
      item2:
        one: "some"
        two: "some string"

Then, in your go code

type Config struct {
    Items map[string]Item
}

type Item struct {
    One string
    Two string
}

Then with

fmt.Printf("%+v\n", c.Items)

you will have

map[item1:{One:some Two:some string} item2:{One:some Two:some string}]

There are multiple problems with your mapping:

  • Item struct members are not exported. You have to export them:
type Item struct {
    One string `yaml:"one"`
    Two string `yaml:"two"`
}
  • Items is an array of map of Items
type conf struct {
    Items []map[string]Item `yaml:"items"`
}

My occasion is, I defined the yaml as the following:

idl:
  protobuf:
    executable: protoc
    version_min: v3.6.0
    version_cmd: "protoc --version | awk '{ print $2 }'"
    install_cmd: ""
    fallback: "please install protoc first, see: https://github.com/protocolbuffers/protobuf"
  flatbuffers:
    executable: flatc
    version_min: 2.0.0
    version_cmd: "flatc --version | awk '{ print $3 }'"
    install_cmd: ""
    fallback: "please install flatc first, see: https://google.github.io/flatbuffers/flatbuffers_guide_building.html"

I want to convert the yaml to type Config, which is defined as:

type Dependency struct {
    Executable string `yaml:"executable"`  
    VersionMin string `yaml:"version_min"` 
    VersionCmd string `yaml:"version_cmd"` 
    InstallCmd string `yaml:"install_cmd"` 
    Fallback   string `yaml:"fallback"`    
}
type Config struct {
    IDL       map[string]*Dependency          `yaml:"idl"`
    ...
}

It reports an error: yaml: unmarshal errors: line 5: cannot unmarshal !!seq into map[string]*config.Dependency.

I searched relevant problems and yaml tutorials, I think my yaml file is OK. I am really confused.

Related