Thanks it works! I changed slightly the unmarshaler to avoid marshaling and unmarshaling the same data.
func (c *Config) UnmarshalYAML(value *yaml.Node) error {
var rawConfig struct {
Rules []map[string]yaml.Node `yaml:"rules"`
}
if err := value.Decode(&rawConfig); err != nil {
return err
}
c.Rules = make([]Rule, 0, len(rawConfig.Rules))
for _, rule := range rawConfig.Rules {
for ruleType, ruleData := range rule {
var rule Rule
switch ruleType {
case "typeA":
var typeA TypeA
if err := ruleData.Decode(&typeA); err != nil {
return err
}
rule = typeA
case "typeB":
var typeB TypeB
if err := ruleData.Decode(&typeB); err != nil {
return err
}
rule = typeB
default:
return fmt.Errorf("unknown rule type: %s", ruleType)
}
c.Rules = append(c.Rules, rule)
}
}
return nil
}
func main() {
var yamlFile = []byte(`
rules:
- typeA:
tic: 1
plop: 4
- typeB:
tic: 1
tac: 3
plip: 4
- typeA:
tic: 5
plop: 7
`)
var config Config
err := yaml.Unmarshal(yamlFile, &config)
if err != nil {
log.Fatalf("Error when parsing YAML file: %v", err)
}
for _, rule := range config.Rules {
fmt.Println(rule.Type(), rule)
}
}