value.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. package muesli
  2. import "fmt"
  3. /* Run time values */
  4. type Value interface {
  5. String() string
  6. Type() TypeValue
  7. }
  8. type IntValue int64
  9. type FloatValue float64
  10. type StringValue string
  11. type BoolValue bool
  12. type WordValue string
  13. type TypeValue string
  14. type ErrorValue struct {
  15. error
  16. }
  17. type EmptyValue struct {
  18. }
  19. type ListValue struct {
  20. List []Value
  21. }
  22. // Values is simply a shorthand alias for []Value
  23. type Values = []Value
  24. const (
  25. TrueValue = BoolValue(true)
  26. FalseValue = BoolValue(false)
  27. IntTypeValue = TypeValue("Int")
  28. FloatTypeValue = TypeValue("Float")
  29. StringTypeValue = TypeValue("String")
  30. BoolTypeValue = TypeValue("Bool")
  31. WordTypeValue = TypeValue("Word")
  32. ErrorTypeValue = TypeValue("Error")
  33. TypeTypeValue = TypeValue("Type")
  34. EmptyTypeValue = TypeValue("Empty")
  35. ListTypeValue = TypeValue("List")
  36. AnyTypeValue = TypeValue("Any")
  37. )
  38. var NilValue = Value(nil)
  39. func (val IntValue) String() string {
  40. return fmt.Sprintf("%d", int64(val))
  41. }
  42. func (val FloatValue) String() string {
  43. return fmt.Sprintf("%f", float64(val))
  44. }
  45. func (val BoolValue) String() string {
  46. if bool(val) {
  47. return "true"
  48. } else {
  49. return "false"
  50. }
  51. }
  52. func (val StringValue) String() string {
  53. return string(val)
  54. }
  55. func (val WordValue) String() string {
  56. return string(val)
  57. }
  58. func (val TypeValue) String() string {
  59. return string(val)
  60. }
  61. func (val ErrorValue) String() string {
  62. return fmt.Sprintf("%s", val.Error())
  63. }
  64. func (val EmptyValue) String() string {
  65. return "<empty>"
  66. }
  67. func (val ListValue) String() string {
  68. res := "["
  69. sep := ""
  70. for _, elt := range val.List {
  71. res = res + sep + elt.String()
  72. sep = ", "
  73. }
  74. res += "]"
  75. return res
  76. }
  77. func (v IntValue) Type() TypeValue { return IntTypeValue }
  78. func (v FloatValue) Type() TypeValue { return FloatTypeValue }
  79. func (v StringValue) Type() TypeValue { return StringTypeValue }
  80. func (v BoolValue) Type() TypeValue { return BoolTypeValue }
  81. func (v WordValue) Type() TypeValue { return WordTypeValue }
  82. func (v TypeValue) Type() TypeValue { return TypeTypeValue }
  83. func (v ErrorValue) Type() TypeValue { return ErrorTypeValue }
  84. func (v EmptyValue) Type() TypeValue { return EmptyTypeValue }
  85. func (v ListValue) Type() TypeValue { return ListTypeValue }
  86. func NewErrorValuef(format string, args ...interface{}) ErrorValue {
  87. err := fmt.Errorf(format, args...)
  88. return ErrorValue{err}
  89. }
  90. func NewListValue(elements ...Value) ListValue {
  91. return ListValue{elements}
  92. }
  93. func (list *ListValue) Append(elements ...Value) {
  94. list.List = append(list.List, elements...)
  95. }
  96. func EmptyListValue() ListValue {
  97. return ListValue{make([]Value, 0)}
  98. }
  99. func EmptyValueArray() []Value {
  100. return make([]Value, 0)
  101. }
  102. func NewValueArray(elements ...Value) []Value {
  103. return elements
  104. }
  105. /* Helpers to easily convert Muesli values to "normal" Go values. */
  106. func From(from Value, to interface{}) error {
  107. switch val := from.(type) {
  108. case WordValue:
  109. (*to.(*string)) = string(val)
  110. case StringValue:
  111. (*to.(*string)) = string(val)
  112. case TypeValue:
  113. (*to.(*string)) = string(val)
  114. case IntValue:
  115. (*to.(*int64)) = int64(val)
  116. case FloatValue:
  117. (*to.(*float64)) = float64(val)
  118. case BoolValue:
  119. (*to.(*bool)) = bool(val)
  120. case ErrorValue:
  121. return val.error
  122. default:
  123. return fmt.Errorf("Cannot convert value %v to %v", from, to)
  124. }
  125. return nil
  126. }
  127. /* Helpers to easily convert Muesli values from "normal" Go values. */
  128. func To(from interface{}) Value {
  129. switch val := from.(type) {
  130. case string:
  131. return StringValue(val)
  132. case int8:
  133. return IntValue(val)
  134. case int16:
  135. return IntValue(val)
  136. case int32:
  137. return IntValue(val)
  138. case int64:
  139. return IntValue(val)
  140. case int:
  141. return IntValue(val)
  142. case bool:
  143. return BoolValue(val)
  144. case float32:
  145. return FloatValue(val)
  146. case float64:
  147. return FloatValue(val)
  148. case error:
  149. return ErrorValue{val}
  150. case Value:
  151. return val
  152. default:
  153. return NewErrorValuef("Cannot convert value %v", from)
  154. }
  155. }
  156. func ListTo(froms ...interface{}) []Value {
  157. list := make([]Value, 0)
  158. for _, from := range froms {
  159. val := To(from)
  160. list = append(list, val)
  161. }
  162. return list
  163. }
  164. func ListFrom(froms []Value, tos ...interface{}) error {
  165. for i, from := range froms {
  166. if i >= len(tos) {
  167. break
  168. }
  169. err := From(from, tos[i])
  170. if err != nil {
  171. return err
  172. }
  173. }
  174. return nil
  175. }
  176. func ListFromList(froms []Value) []interface{} {
  177. res := make([]interface{}, len(froms))
  178. for i, from := range froms {
  179. res[i] = from
  180. }
  181. return res
  182. }