value.go

  1package ast
  2
  3import (
  4	"fmt"
  5	"strconv"
  6	"strings"
  7)
  8
  9type ValueKind int
 10
 11const (
 12	Variable ValueKind = iota
 13	IntValue
 14	FloatValue
 15	StringValue
 16	BlockValue
 17	BooleanValue
 18	NullValue
 19	EnumValue
 20	ListValue
 21	ObjectValue
 22)
 23
 24type Value struct {
 25	Raw      string
 26	Children ChildValueList
 27	Kind     ValueKind
 28	Position *Position `dump:"-"`
 29
 30	// Require validation
 31	Definition         *Definition
 32	VariableDefinition *VariableDefinition
 33	ExpectedType       *Type
 34}
 35
 36type ChildValue struct {
 37	Name     string
 38	Value    *Value
 39	Position *Position `dump:"-"`
 40}
 41
 42func (v *Value) Value(vars map[string]interface{}) (interface{}, error) {
 43	if v == nil {
 44		return nil, nil
 45	}
 46	switch v.Kind {
 47	case Variable:
 48		if value, ok := vars[v.Raw]; ok {
 49			return value, nil
 50		}
 51		if v.VariableDefinition != nil && v.VariableDefinition.DefaultValue != nil {
 52			return v.VariableDefinition.DefaultValue.Value(vars)
 53		}
 54		return nil, nil
 55	case IntValue:
 56		return strconv.ParseInt(v.Raw, 10, 64)
 57	case FloatValue:
 58		return strconv.ParseFloat(v.Raw, 64)
 59	case StringValue, BlockValue, EnumValue:
 60		return v.Raw, nil
 61	case BooleanValue:
 62		return strconv.ParseBool(v.Raw)
 63	case NullValue:
 64		return nil, nil
 65	case ListValue:
 66		var val []interface{}
 67		for _, elem := range v.Children {
 68			elemVal, err := elem.Value.Value(vars)
 69			if err != nil {
 70				return val, err
 71			}
 72			val = append(val, elemVal)
 73		}
 74		return val, nil
 75	case ObjectValue:
 76		val := map[string]interface{}{}
 77		for _, elem := range v.Children {
 78			elemVal, err := elem.Value.Value(vars)
 79			if err != nil {
 80				return val, err
 81			}
 82			val[elem.Name] = elemVal
 83		}
 84		return val, nil
 85	default:
 86		panic(fmt.Errorf("unknown value kind %d", v.Kind))
 87	}
 88}
 89
 90func (v *Value) String() string {
 91	if v == nil {
 92		return "<nil>"
 93	}
 94	switch v.Kind {
 95	case Variable:
 96		return "$" + v.Raw
 97	case IntValue, FloatValue, EnumValue, BooleanValue, NullValue:
 98		return v.Raw
 99	case StringValue, BlockValue:
100		return strconv.Quote(v.Raw)
101	case ListValue:
102		var val []string
103		for _, elem := range v.Children {
104			val = append(val, elem.Value.String())
105		}
106		return "[" + strings.Join(val, ",") + "]"
107	case ObjectValue:
108		var val []string
109		for _, elem := range v.Children {
110			val = append(val, strconv.Quote(elem.Name)+":"+elem.Value.String())
111		}
112		return "{" + strings.Join(val, ",") + "}"
113	default:
114		panic(fmt.Errorf("unknown value kind %d", v.Kind))
115	}
116}
117
118func (v *Value) Dump() string {
119	return v.String()
120}