Как использовать динамические ключи при разборе YAML с viper? - PullRequest
0 голосов
/ 08 сентября 2018

У меня есть следующий файл yml:

# config.yml
items:
  name-of-item: # dynamic field
    source: ...
    destination: ...

И я хочу использовать viper для его анализа, но name-of-item может быть чем угодно, поэтому я не уверен, как это решить. Я знаю, что могу использовать следующее:

// 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)
    }
}

В этом случае я могу разархивировать, потому что я объявляю NameOfItem, но что мне делать, если я не знаю названия поля (или, другими словами, если оно динамическое)?

1 Ответ

0 голосов
/ 08 сентября 2018

Типы struct в Go могут быть не динамическими (я сомневаюсь, что они могут использоваться в любом другом строго типизированном языке), поэтому вы должны использовать двухэтапный процесс:

  1. Разберите соответствующий фрагмент данных в значение типа map[string]interface{}.
  2. Постобработка результата путем перебора ключей карты и используйте утверждения типа для значений, соответствующих конкретным ключам.

Но из вашего вопроса неясно, являются ли ваши данные YAML действительно произвольными или ключ items содержит унифицированный массив элементов - я имею в виду, что каждый элемент состоит из source и destination значения, только ключи для самих предметов не известны.

В этом последнем случае целью для демаршалирования части items должна быть карта - что-то вроде

type Item struct {
  Source string
  Destination string
}

items := make(map[string]Item)

err := viper.Unmarshal(items)
...