Сопоставление вложенного конфига Yaml со структурой
Я новичок в работе, и я использую viper и загружаю все мои настройки, что в настоящее время у меня есть, YAML выглядит следующим образом
countryQueries:
sg:
- qtype: gmap
qplacetype: postal_code
- qtype: gmap
qplacetype: address
- qtype: geocode
qplacetype: street_address
hk:
- qtype: gmap
qplacetype: postal_code
- qtype: gmap
qplacetype: address
- qtype: geocode
qplacetype: street_address
Следует отметить, что код страны является динамическим, его можно добавить в любое время для любых стран. Так как мне сопоставить это со структурой, где технически говоря я могу сделать
for _, query := range countryQueries["sg"] { }
я пытаюсь создать его сам, зацикливая его, но я застрял здесь
for country, queries := range viper.GetStringMap("countryQueries") {
// i cant seem to do anything with queries, which i wish to loop it
for _,query := range queries {} //here error
}
Любая помощь будет высоко ценится
4 ответа
После некоторого прочтения понял, что у viper есть свои собственные возможности демаршалинга, которые прекрасно работают https://github.com/spf13/viper
Итак, что я сделал
type Configuration struct {
Countries map[string][]CountryQuery `mapstructure:"countryQueries"`
}
type CountryQuery struct {
QType string
QPlaceType string
}
func BuildConfig() {
viper.SetConfigName("configFileName")
viper.AddConfigPath("./config")
err := viper.ReadInConfig()
if err != nil {
panic(fmt.Errorf("Error config file: %s \n", err))
}
var config Configuration
err = viper.Unmarshal(&config)
if err != nil {
panic(fmt.Errorf("Unable to decode Config: %s \n", err))
}
}
Если вы хотите нанести на карту свой yaml
структура к строгому Голангу struct
Вы можете использовать библиотеку mapstructure для отображения вложенных пар ключ / значение в каждой стране.
Например:
package main
import (
"github.com/spf13/viper"
"github.com/mitchellh/mapstructure"
"fmt"
"log"
)
type CountryConfig struct {
Qtype string
Qplacetype string
}
type QueryConfig struct {
CountryQueries map[string][]CountryConfig;
}
func NewQueryConfig () QueryConfig {
queryConfig := QueryConfig{}
queryConfig.CountryQueries = map[string][]CountryConfig{}
return queryConfig
}
func main() {
viper.SetConfigName("test")
viper.AddConfigPath(".")
err := viper.ReadInConfig()
queryConfig := NewQueryConfig()
if err != nil {
log.Panic("error:", err)
} else {
mapstructure.Decode(viper.AllSettings(), &queryConfig)
}
for _, config := range queryConfig.CountryQueries["sg"] {
fmt.Println("qtype:", config.Qtype, "qplacetype:", config.Qplacetype)
}
}
Вот простой код с go-yaml:
package main
import (
"fmt"
"gopkg.in/yaml.v2"
"log"
)
var data = `
countryQueries:
sg:
- qtype: gmap
qplacetype: postal_code
- qtype: gmap
qplacetype: address
- qtype: geocode
qplacetype: street_address
hk:
- qtype: gmap
qplacetype: postal_code
- qtype: gmap
qplacetype: address
- qtype: geocode
qplacetype: street_address
`
func main() {
m := make(map[interface{}]interface{})
err := yaml.Unmarshal([]byte(data), &m)
if err != nil {
log.Fatalf("error: %v", err)
}
fmt.Printf("%v\n", m)
}
Вы можете использовать этот пакет https://github.com/go-yaml/yaml для сериализации / десериализации YAML в Go.