package muesli // Value interface type for Muesli run time values that the language works with. type Value interface { // String because a value must be convertible to string. // This string is then used as the hash key in MapValue and for debugging. String() string // Type returns the type of the value. Muesli has typed values. Type() TypeValue // Convert the value to a different go value which must be passed // in as a pointer to which the value must be set, // or return an error if the conversion is not possible. Convert(to interface{}) error } /* Helpers to easily convert Muesli values to "normal" Go values. */ func From(from Value, to interface{}) error { return from.Convert(to) } // ParseOptArgs is helper to easily convert Muesli value lists to "normal" // Go values. args is the input, required is the amount of required aruments, // and to are pointers to where to store the data. The args are converted by // calling the Convert() method on them. // The returned array contains the remaining unparsed arguments. func ParseOptArgs(args []Value, required int, to...interface{}) ([]Value, error) { if required > len(args) { return nil, NewErrorValuef("Too few arguments, expected %d, got %d", required, len(args)) } stop := len(args) if len(to) < stop { stop = len(to) } i:= 0 for ; i < stop ; i ++ { fromElt := args[i] toElt := to[i] if fromElt == nil { return nil, NewErrorValuef("Nil pointer to result %d", i) } err := fromElt.Convert(toElt) if err != nil { return nil, err } } rest := args[i:len(args)] return rest, nil } // ParseArgs is helper to easily convert Muesli value lists to "normal" // Go values. It is the same as ParseOptArgs(args, len(to), to...) func ParseArgs(args []Value, to...interface{}) ([]Value, error) { return ParseOptArgs(args, len(to), to...) } /* Helpers to easily convert Muesli value lists to "normal" Go values in slices. */ func ParseArgsToIntSlice(args []Value) ([]int, error) { res := []int{} for _, arg := range args{ value := int(0) err := arg.Convert(&value) if err != nil { return res, err } res = append(res, value) } return res, nil } /* Helpers to easily convert Muesli value lists to "normal" Go values in slices. */ func ParseArgsToFloat64Slice(args []Value) ([]float64, error) { res := []float64{} for _, arg := range args{ value := float64(0.0) err := arg.Convert(&value) if err != nil { return res, err } res = append(res, value) } return res, 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 } func Return(args ... Value) []Value { return args } func ReturnEmpty() []Value { return []Value{EmptyValue{}} } func ReturnError(err error) []Value { return []Value{ErrorValue{err}} } func Ok(args ... Value) []Value { return args } func Fail(err error) []Value { return []Value{ErrorValue{err}} } func None() []Value { return []Value{EmptyValue{}} } func BoolOk(b bool) []Value{ return []Value{BoolValue(b)} } func IntOk(i int) []Value{ return []Value{IntValue(i)} } func FloatOk(f float64) []Value{ return []Value{FloatValue(f)} }