Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unmarshal YAML into unknown struct

Tags:

yaml

go

Sorry for the confusing title, I'm having trouble wording this question. So lets say I have a YAML config file like this

animals:
  -
    type: whale
    options:
      color: blue
      name: Mr. Whale
    features:
       -
         type: musician
         options:
           instruments:
             - Guitar
             - Violin

Very contrived example, but it's directly analogous to what I'm really working with.

So now I have some structs to marshal this config into

type Config struct {
  AnimalConfigs []*AnimalConfig `yaml:"animals"`
}

type AnimalConfig struct{
  Type string
  Options map[string]string // ????
  Features []*FeatureConfig
}

type FeatureConfig struct{
  Type string
  Options ????
}

So the problem here is that the animal types (whale, etc..), and features (musician, etc...) are not determined ahead of time, they can be added on as separate modules and can each have their own configurations. So say someone is using this library and wants to add their own animal. I do not know what this animal is, what it's options will be, and what it's features will be. I also don't know the structure of the feature's. All I know is that it will have a type property, and an options property. I would like the developer to be able to add custom animals and features, and my library can just do something like YourAnimal.Create(yourConfig).

I'm using the go-yaml library. As you can see in the AnimalConfig struct, my initial idea was to have the options and features just be map[string]string, and then let the custom module unmarshal that string into their own struct, but that wouldn't work for example with the musician feature because instruments is a list, not a string. Thanks!

like image 616
Weston Avatar asked Nov 08 '22 03:11

Weston


1 Answers

I think in general what you are asking is how to unmarshal YAML when you don't know the structure which will be produced, yes? If so, what I've done is use ghodss/yaml to convert YAML to JSON, then use the standard encoding/json to unmarshal. This gets you a struct with everything in the YAML doc, but you have to "type switch" your way through it, and key names, of course, may not be known a prioir.

Here's an example: https://play.golang.org/p/8mcuot-lw0y

like image 64
greg.carter Avatar answered Nov 15 '22 07:11

greg.carter