Skip to content
Snippets Groups Projects
variables.go 1.37 KiB
Newer Older

	"gopkg.in/yaml.v3"
)

// Variable ...
type Variable struct {
	Name  string
	Value interface{}
}

type Variables []Variable

func (v *Variables) UnmarshalYAML(node *yaml.Node) error {
	if err := node.Decode((*[]Variable)(v)); err == nil {
		return nil
	}
	if node.Kind != yaml.MappingNode {
		return fmt.Errorf("expects a mapping, got: %d", node.Kind)
	}
	*v = make(Variables, 0, len(node.Content)/2)
	var next Variable
	for i, content := range node.Content {
		if i%2 == 0 {
			content.Decode(&next.Name)
		} else {
			content.Decode(&next.Value)
			*v = append(*v, next)
		}
	}
	return nil
}

func lookupVariable(variables map[string]interface{}, name string) (interface{}, bool) {
	path := strings.Split(name, ".")

	var v interface{} = variables
	var ok bool
	for _, key := range path {
		v, ok = lookupVariableHelper(v, key)
		if !ok {
			return nil, false
		}
	}
	return v, true
}

func lookupVariableHelper(v interface{}, key string) (interface{}, bool) {
	switch t := v.(type) {
	case map[string]interface{}:
		ret, ok := t[key]
		return ret, ok
	case map[interface{}]interface{}:
		ret, ok := t[key]
		return ret, ok
	case []interface{}:
		index, err := strconv.Atoi(key)
		if err != nil {
			return nil, false
		}
		if index >= len(t) || index < 0 {
			return nil, false
		}
		return t[index], true
	default:
		return nil, false
	}
}