Skip to content

Instantly share code, notes, and snippets.

@overhacked
Created July 27, 2019 23:40
Show Gist options
  • Save overhacked/5b556f14b457ea49e70bf871a5b9fe98 to your computer and use it in GitHub Desktop.
Save overhacked/5b556f14b457ea49e70bf871a5b9fe98 to your computer and use it in GitHub Desktop.
Idea for multivariant structs in go-yaml (for zrepl)
package main
import (
"fmt"
"log"
"gopkg.in/yaml.v2"
)
// An example showing how to unmarshal embedded
// structs from YAML.
type Hooks struct {
PreHook string `yaml:"pre"`
PostHook string `yaml:"post"`
Timeout TimeoutSingleOrMulti `yaml:"timeout"`
}
type TimeoutSingleOrMulti struct {
Ret interface{}
}
type Timeouts struct {
Pre int `yaml:"pre"`
Post int `yaml:"post"`
}
func (timeouts *TimeoutSingleOrMulti) UnmarshalYAML(unmarshal func(interface{}) error) error {
var globalTimeout int
var multiTimeout Timeouts
if err := unmarshal(&globalTimeout); err != nil {
if err := unmarshal(&multiTimeout); err != nil {
return err
}
} else {
multiTimeout.Pre = globalTimeout
multiTimeout.Post = globalTimeout
timeouts.Ret = multiTimeout
}
timeouts.Ret = multiTimeout
return nil
}
/*
var data = `
pre: foo.sh
post: bar.sh
timeout:
pre: 30
post: 60
`
*/
var data = `
pre: foo.sh
post: bar.sh
timeout: 90
`
func main() {
var hooks Hooks
err := yaml.Unmarshal([]byte(data), &hooks)
if err != nil {
log.Fatalf("cannot unmarshal data: %v", err)
}
fmt.Printf("%+v\n", hooks)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment