I have the following yml file:
# config.yml
items:
name-of-item: # dynamic field
source: ...
destination: ...
And I want to use viper to parse it, but name-of-item
can be anything, so I'm not sure how to solve that. I know that I could use the following:
// inside config folder
package config
type Items struct {
NameOfItem NameOfItem
}
type NameOfItem struct {
Source string
Destination string
}
// inside main.go
package main
import (
"github.com/spf13/viper"
"log"
"github.com/username/lib/config"
)
func main() {
viper.SetConfigName("config.yml")
viper.AddConfigPath(".")
var configuration config.Item
if err := viper.ReadInConfig(); err != nil {
log.Fatalf("Error reading config file, %s", err)
}
err := viper.Unmarshal(&configuration)
if err != nil {
log.Fatalf("unable to decode into struct, %v", err)
}
}
In this case, I can unmarshal because I'm declaring NameOfItem
, but what should I do if I don't know the name of the field (or in other words, if it's dynamic)?
The struct
types in Go may not be dynamic (I doubt they may in any other strictly-typed language), so you have to use a two stage process:
map[string]interface{}
.But it's not clear from your question whether your YAML data are really arbitrary or the items
key contains a uniform array of items—I mean, each item consists of the source
and destination
values, just the keys for the items themselves are not known.
In this latter case, the target for the unmarshaling of the items
piece should be a map—something like
type Item struct {
Source string
Destination string
}
items := make(map[string]Item)
err := viper.Unmarshal(items)