value.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. package muesli
  2. // Value interface type for Muesli run time values that the language works with.
  3. type Value interface {
  4. // String because a value must be convertible to string.
  5. // This string is then used as the hash key in MapValue and for debugging.
  6. String() string
  7. // Type returns the type of the value. Muesli has typed values.
  8. Type() TypeValue
  9. // Convert the value to a different go value which must be passed
  10. // in as a pointer to which the value must be set,
  11. // or return an error if the conversion is not possible.
  12. Convert(to interface{}) error
  13. }
  14. /* Helpers to easily convert Muesli values to "normal" Go values. */
  15. func From(from Value, to interface{}) error {
  16. return from.Convert(to)
  17. }
  18. // ParseOptArgs is helper to easily convert Muesli value lists to "normal"
  19. // Go values. args is the input, required is the amount of required aruments,
  20. // and to are pointers to where to store the data. The args are converted by
  21. // calling the Convert() method on them.
  22. // The returned array contains the remaining unparsed arguments.
  23. func ParseOptArgs(args []Value, required int, to...interface{}) ([]Value, error) {
  24. if required > len(args) {
  25. return nil, NewErrorValuef("Too few arguments, expected %d, got %d", required, len(args))
  26. }
  27. stop := len(args)
  28. if len(to) < stop {
  29. stop = len(to)
  30. }
  31. i:= 0
  32. for ; i < stop ; i ++ {
  33. fromElt := args[i]
  34. toElt := to[i]
  35. if fromElt == nil {
  36. return nil, NewErrorValuef("Nil pointer to result %d", i)
  37. }
  38. err := fromElt.Convert(toElt)
  39. if err != nil {
  40. return nil, err
  41. }
  42. }
  43. rest := args[i:len(args)]
  44. return rest, nil
  45. }
  46. // ParseArgs is helper to easily convert Muesli value lists to "normal"
  47. // Go values. It is the same as ParseOptArgs(args, len(to), to...)
  48. func ParseArgs(args []Value, to...interface{}) ([]Value, error) {
  49. return ParseOptArgs(args, len(to), to...)
  50. }
  51. /* Helpers to easily convert Muesli value lists to "normal" Go values in slices. */
  52. func ParseArgsToIntSlice(args []Value) ([]int, error) {
  53. res := []int{}
  54. for _, arg := range args{
  55. value := int(0)
  56. err := arg.Convert(&value)
  57. if err != nil {
  58. return res, err
  59. }
  60. res = append(res, value)
  61. }
  62. return res, nil
  63. }
  64. /* Helpers to easily convert Muesli value lists to "normal" Go values in slices. */
  65. func ParseArgsToFloat64Slice(args []Value) ([]float64, error) {
  66. res := []float64{}
  67. for _, arg := range args{
  68. value := float64(0.0)
  69. err := arg.Convert(&value)
  70. if err != nil {
  71. return res, err
  72. }
  73. res = append(res, value)
  74. }
  75. return res, nil
  76. }
  77. /* Helpers to easily convert Muesli values from "normal" Go values. */
  78. func To(from interface{}) Value {
  79. switch val := from.(type) {
  80. case string:
  81. return StringValue(val)
  82. case int8:
  83. return IntValue(val)
  84. case int16:
  85. return IntValue(val)
  86. case int32:
  87. return IntValue(val)
  88. case int64:
  89. return IntValue(val)
  90. case int:
  91. return IntValue(val)
  92. case bool:
  93. return BoolValue(val)
  94. case float32:
  95. return FloatValue(val)
  96. case float64:
  97. return FloatValue(val)
  98. case error:
  99. return ErrorValue{val}
  100. case Value:
  101. return val
  102. default:
  103. return NewErrorValuef("Cannot convert value %v", from)
  104. }
  105. }
  106. func ListTo(froms ...interface{}) []Value {
  107. list := make([]Value, 0)
  108. for _, from := range froms {
  109. val := To(from)
  110. list = append(list, val)
  111. }
  112. return list
  113. }
  114. func ListFrom(froms []Value, tos ...interface{}) error {
  115. for i, from := range froms {
  116. if i >= len(tos) {
  117. break
  118. }
  119. err := From(from, tos[i])
  120. if err != nil {
  121. return err
  122. }
  123. }
  124. return nil
  125. }
  126. func ListFromList(froms []Value) []interface{} {
  127. res := make([]interface{}, len(froms))
  128. for i, from := range froms {
  129. res[i] = from
  130. }
  131. return res
  132. }
  133. func Return(args ... Value) []Value {
  134. return args
  135. }
  136. func ReturnEmpty() []Value {
  137. return []Value{EmptyValue{}}
  138. }
  139. func ReturnError(err error) []Value {
  140. return []Value{ErrorValue{err}}
  141. }
  142. func Ok(args ... Value) []Value {
  143. return args
  144. }
  145. func Fail(err error) []Value {
  146. return []Value{ErrorValue{err}}
  147. }
  148. func None() []Value {
  149. return []Value{EmptyValue{}}
  150. }
  151. func BoolOk(b bool) []Value{
  152. return []Value{BoolValue(b)}
  153. }
  154. func IntOk(i int) []Value{
  155. return []Value{IntValue(i)}
  156. }
  157. func FloatOk(f float64) []Value{
  158. return []Value{FloatValue(f)}
  159. }