yaml
// - zeros.go -
// This is an example of handling default values (zero values) with yaml
package main
import (
"fmt"
"sort"
"strings"
"github.com/davecgh/go-spew/spew"
"gopkg.in/yaml.v2"
)
type count uint64
func (c *count) IsZero() bool {
return c == nil
}
func main() {
tests := map[string]string{
"with zero": " count: 0",
"with none": " some: none",
"with nums": " count: 1",
}
var keys []string
for k, _ := range tests {
keys = append(keys, k)
}
sort.Strings(keys)
for _, key := range keys {
var (
lines_of_yaml = []string{
"main:",
tests[key],
` found: string`,
}
in = []byte(strings.Join(lines_of_yaml, "\n"))
out struct {
Main struct {
Num *count `yaml:"count,omitempty"`
// Test int `yaml:"testnum,omitempty"`
} `yaml:"main"`
}
)
fmt.Println(strings.Repeat("\n", 2))
fmt.Println(strings.Repeat("*", 4) + " " + key + " " + strings.Repeat("*", 65))
// with 0 -> we have 0
fmt.Println("In....")
fmt.Println(strings.Repeat("=", 80))
if err := yaml.Unmarshal(in, &out); err == nil {
spew.Dump(out)
// spew.Println(out)
} else {
fmt.Printf("error: %v\n", err)
}
fmt.Println("Out....")
fmt.Println(strings.Repeat("=", 80))
// out.Main.Test = 10
if b, err := yaml.Marshal(out); err == nil {
fmt.Println(string(b))
}
fmt.Println(strings.Repeat("\n", 2))
}
}
// - unmarshaling.go -
package main
import (
"errors"
"fmt"
"log"
"gopkg.in/yaml.v2"
)
type VariableType int
const (
IsString VariableType = iota
IsInt
IsIntSlice
)
type Variable struct {
Type VariableType
Value interface{}
}
func (v *Variable) UnmarshalYAML(unmarshal func(interface{}) error) error {
errCantValidate := errors.New("can't unmarshal value")
type plainUint uint
number := new(uint)
if err := unmarshal((*plainUint)(number)); err == nil {
v.Type = IsInt
v.Value = *number
return nil
}
type plainString string
str := new(string)
if err := unmarshal((*plainString)(str)); err == nil {
v.Type = IsString
v.Value = *str
return nil
}
type plainIntSlice []int
var intSlice []int
if err := unmarshal((*plainIntSlice)(&intSlice)); err == nil {
v.Type = IsIntSlice
v.Value = intSlice
return nil
}
return errCantValidate
}
func main() {
yamls := []string{
`variable: 1`,
`variable: boo`,
`variable: [1,2]`,
}
for _, body := range yamls {
var v struct {
Data Variable `yaml:"variable"`
}
if err := yaml.Unmarshal([]byte(body), &v); err != nil {
log.Printf("error: %w\n", err)
} else {
fmt.Printf("yaml - %s\n", body)
fmt.Printf("var - %#v\n", v)
}
fmt.Println()
}
}