package muesli import "fmt" /* Run time values */ type Value interface { String() string Type() TypeValue } type IntValue int64 type FloatValue float64 type StringValue string type BoolValue bool type WordValue string type TypeValue string type ErrorValue struct { error } type EmptyValue struct { } type ListValue struct { List []Value } // Values is simply a shorthand alias for []Value type Values = []Value const ( TrueValue = BoolValue(true) FalseValue = BoolValue(false) IntTypeValue = TypeValue("Int") FloatTypeValue = TypeValue("Float") StringTypeValue = TypeValue("String") BoolTypeValue = TypeValue("Bool") WordTypeValue = TypeValue("Word") ErrorTypeValue = TypeValue("Error") TypeTypeValue = TypeValue("Type") EmptyTypeValue = TypeValue("Empty") ListTypeValue = TypeValue("List") AnyTypeValue = TypeValue("Any") ) var NilValue = Value(nil) func (val IntValue) String() string { return fmt.Sprintf("%d", int64(val)) } func (val FloatValue) String() string { return fmt.Sprintf("%f", float64(val)) } func (val BoolValue) String() string { if bool(val) { return "true" } else { return "false" } } func (val StringValue) String() string { return string(val) } func (val WordValue) String() string { return string(val) } func (val TypeValue) String() string { return string(val) } func (val ErrorValue) String() string { return fmt.Sprintf("%s", val.Error()) } func (val EmptyValue) String() string { return "" } func (val ListValue) String() string { res := "[" sep := "" for _, elt := range val.List { res = res + sep + elt.String() sep = ", " } res += "]" return res } func (v IntValue) Type() TypeValue { return IntTypeValue } func (v FloatValue) Type() TypeValue { return FloatTypeValue } func (v StringValue) Type() TypeValue { return StringTypeValue } func (v BoolValue) Type() TypeValue { return BoolTypeValue } func (v WordValue) Type() TypeValue { return WordTypeValue } func (v TypeValue) Type() TypeValue { return TypeTypeValue } func (v ErrorValue) Type() TypeValue { return ErrorTypeValue } func (v EmptyValue) Type() TypeValue { return EmptyTypeValue } func (v ListValue) Type() TypeValue { return ListTypeValue } func NewErrorValuef(format string, args ...interface{}) ErrorValue { err := fmt.Errorf(format, args...) return ErrorValue{err} } func NewListValue(elements ...Value) ListValue { return ListValue{elements} } func (list *ListValue) Append(elements ...Value) { list.List = append(list.List, elements...) } func EmptyListValue() ListValue { return ListValue{make([]Value, 0)} } func EmptyValueArray() []Value { return make([]Value, 0) } func NewValueArray(elements ...Value) []Value { return elements } /* Helpers to easily convert Muesli values to "normal" Go values. */ func From(from Value, to interface{}) error { switch val := from.(type) { case WordValue: (*to.(*string)) = string(val) case StringValue: (*to.(*string)) = string(val) case TypeValue: (*to.(*string)) = string(val) case IntValue: (*to.(*int64)) = int64(val) case FloatValue: (*to.(*float64)) = float64(val) case BoolValue: (*to.(*bool)) = bool(val) case ErrorValue: return val.error default: return fmt.Errorf("Cannot convert value %v to %v", from, to) } return nil } /* Helpers to easily convert Muesli values from "normal" Go values. */ func To(from interface{}) Value { switch val := from.(type) { case string: return StringValue(val) case int8: return IntValue(val) case int16: return IntValue(val) case int32: return IntValue(val) case int64: return IntValue(val) case int: return IntValue(val) case bool: return BoolValue(val) case float32: return FloatValue(val) case float64: return FloatValue(val) case error: return ErrorValue{val} case Value: return val default: return NewErrorValuef("Cannot convert value %v", from) } } func ListTo(froms ...interface{}) []Value { list := make([]Value, 0) for _, from := range froms { val := To(from) list = append(list, val) } return list } func ListFrom(froms []Value, tos ...interface{}) error { for i, from := range froms { if i >= len(tos) { break } err := From(from, tos[i]) if err != nil { return err } } return nil } func ListFromList(froms []Value) []interface{} { res := make([]interface{}, len(froms)) for i, from := range froms { res[i] = from } return res }