value.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. package muesli
  2. import "fmt"
  3. /* Run time values */
  4. type Value interface {
  5. String() string
  6. Type() TypeValue
  7. // Convert the value to a normal go value which must be passed
  8. // in as a pointer to which the value mmust be set,
  9. // or return an error if the concversion is not possible.
  10. Convert(to interface{}) error
  11. }
  12. type IntValue int64
  13. type FloatValue float64
  14. type StringValue string
  15. type BoolValue bool
  16. type WordValue string
  17. type TypeValue string
  18. type ErrorValue struct {
  19. error
  20. }
  21. type EmptyValue struct {
  22. }
  23. type ListValue struct {
  24. List []Value
  25. }
  26. // Values is simply a shorthand alias for []Value
  27. type Values = []Value
  28. const (
  29. TrueValue = BoolValue(true)
  30. FalseValue = BoolValue(false)
  31. IntTypeValue = TypeValue("Int")
  32. FloatTypeValue = TypeValue("Float")
  33. StringTypeValue = TypeValue("String")
  34. BoolTypeValue = TypeValue("Bool")
  35. WordTypeValue = TypeValue("Word")
  36. ErrorTypeValue = TypeValue("Error")
  37. TypeTypeValue = TypeValue("Type")
  38. EmptyTypeValue = TypeValue("Empty")
  39. ListTypeValue = TypeValue("List")
  40. AnyTypeValue = TypeValue("Any")
  41. )
  42. var NilValue = Value(nil)
  43. func (val IntValue) String() string {
  44. return fmt.Sprintf("%d", int64(val))
  45. }
  46. func (val FloatValue) String() string {
  47. return fmt.Sprintf("%f", float64(val))
  48. }
  49. func (val BoolValue) String() string {
  50. if bool(val) {
  51. return "true"
  52. } else {
  53. return "false"
  54. }
  55. }
  56. func (val StringValue) String() string {
  57. return string(val)
  58. }
  59. func (val WordValue) String() string {
  60. return string(val)
  61. }
  62. func (val TypeValue) String() string {
  63. return string(val)
  64. }
  65. func (val ErrorValue) String() string {
  66. return fmt.Sprintf("%s", val.Error())
  67. }
  68. func (val EmptyValue) String() string {
  69. return "<empty>"
  70. }
  71. func (val ListValue) String() string {
  72. res := "["
  73. sep := ""
  74. for _, elt := range val.List {
  75. res = res + sep + elt.String()
  76. sep = ", "
  77. }
  78. res += "]"
  79. return res
  80. }
  81. func (v IntValue) Type() TypeValue { return IntTypeValue }
  82. func (v FloatValue) Type() TypeValue { return FloatTypeValue }
  83. func (v StringValue) Type() TypeValue { return StringTypeValue }
  84. func (v BoolValue) Type() TypeValue { return BoolTypeValue }
  85. func (v WordValue) Type() TypeValue { return WordTypeValue }
  86. func (v TypeValue) Type() TypeValue { return TypeTypeValue }
  87. func (v ErrorValue) Type() TypeValue { return ErrorTypeValue }
  88. func (v EmptyValue) Type() TypeValue { return EmptyTypeValue }
  89. func (v ListValue) Type() TypeValue { return ListTypeValue }
  90. func NewErrorValuef(format string, args ...interface{}) ErrorValue {
  91. err := fmt.Errorf(format, args...)
  92. return ErrorValue{err}
  93. }
  94. func NewListValue(elements ...Value) ListValue {
  95. return ListValue{elements}
  96. }
  97. func (list *ListValue) Append(elements ...Value) {
  98. list.List = append(list.List, elements...)
  99. }
  100. func (list *ListValue) AppendList(toAppend ListValue) {
  101. list.List = append(list.List, toAppend.List...)
  102. }
  103. func (list ListValue) Length() int {
  104. return len(list.List)
  105. }
  106. func (list *ListValue) Index(i int) Value {
  107. if i >= len(list.List) {
  108. return NilValue
  109. }
  110. return list.List[i]
  111. }
  112. func (list *ListValue) First() Value {
  113. return list.Index(0)
  114. }
  115. func (list *ListValue) Last() Value {
  116. return list.Index(list.Length()-1)
  117. }
  118. func EmptyListValue() ListValue {
  119. return ListValue{make([]Value, 0)}
  120. }
  121. func EmptyValueArray() []Value {
  122. return make([]Value, 0)
  123. }
  124. func NewValueArray(elements ...Value) []Value {
  125. return elements
  126. }
  127. func (from IntValue) Convert(to interface{}) error {
  128. switch toPtr := to.(type) {
  129. case *string:
  130. (*toPtr) = from.String()
  131. case *int8:
  132. (*toPtr) = int8(from)
  133. case *int16:
  134. (*toPtr) = int16(from)
  135. case *int32:
  136. (*toPtr) = int32(from)
  137. case *int64:
  138. (*toPtr) = int64(from)
  139. case *int:
  140. (*toPtr) = int(from)
  141. case *bool:
  142. (*toPtr) = (from != 0)
  143. case *float32:
  144. (*toPtr) = float32(from)
  145. case *float64:
  146. (*toPtr) = float64(from)
  147. default:
  148. return NewErrorValuef("Cannot convert value %v to %v", from, to)
  149. }
  150. return nil
  151. }
  152. func (from FloatValue) Convert(to interface{}) error {
  153. switch toPtr := to.(type) {
  154. case *string:
  155. (*toPtr) = from.String()
  156. case *int8:
  157. (*toPtr) = int8(from)
  158. case *int16:
  159. (*toPtr) = int16(from)
  160. case *int32:
  161. (*toPtr) = int32(from)
  162. case *int64:
  163. (*toPtr) = int64(from)
  164. case *int:
  165. (*toPtr) = int(from)
  166. case *bool:
  167. (*toPtr) = (from != 0)
  168. case *float32:
  169. (*toPtr) = float32(from)
  170. case *float64:
  171. (*toPtr) = float64(from)
  172. default:
  173. return NewErrorValuef("Cannot convert value %v to %v", from, to)
  174. }
  175. return nil
  176. }
  177. func (from StringValue) Convert(to interface{}) error {
  178. switch toPtr := to.(type) {
  179. case *string:
  180. (*toPtr) = from.String()
  181. default:
  182. return NewErrorValuef("Cannot convert value %v to %v", from, to)
  183. }
  184. return nil
  185. }
  186. func (from WordValue) Convert(to interface{}) error {
  187. switch toPtr := to.(type) {
  188. case *string:
  189. (*toPtr) = from.String()
  190. default:
  191. return NewErrorValuef("Cannot convert value %v to %v", from, to)
  192. }
  193. return nil
  194. }
  195. func (from TypeValue) Convert(to interface{}) error {
  196. switch toPtr := to.(type) {
  197. case *string:
  198. (*toPtr) = from.String()
  199. default:
  200. return NewErrorValuef("Cannot convert value %v to %v", from, to)
  201. }
  202. return nil
  203. }
  204. func (from BoolValue) Convert(to interface{}) error {
  205. switch toPtr := to.(type) {
  206. case *bool:
  207. (*toPtr) = bool(from)
  208. default:
  209. return NewErrorValuef("Cannot convert value %v to %v", from, to)
  210. }
  211. return nil
  212. }
  213. func (from ErrorValue) Convert(to interface{}) error {
  214. switch toPtr := to.(type) {
  215. case *string:
  216. (*toPtr) = from.String()
  217. case *error:
  218. (*toPtr) = from.error
  219. default:
  220. return NewErrorValuef("Cannot convert value %v to %v", from, to)
  221. }
  222. return nil
  223. }
  224. func (from EmptyValue) Convert(to interface{}) error {
  225. return NewErrorValuef("Cannot convert the empty value %v to %v", from, to)
  226. }
  227. func (from ListValue) Convert(to interface{}) error {
  228. switch toPtr := to.(type) {
  229. case *[]Value:
  230. (*toPtr) = from.List
  231. default:
  232. return NewErrorValuef("Cannot convert value %v to %v", from, to)
  233. }
  234. return nil
  235. }
  236. /* Helpers to easily convert Muesli values to "normal" Go values. */
  237. func From(from Value, to interface{}) error {
  238. return from.Convert(to)
  239. }
  240. /* Helpers to easily convert Muesli value lists to "normal" Go values. */
  241. func ParseArgs(args []Value, to...interface{}) ([]interface{}, error) {
  242. if len(to) > len(args) {
  243. return nil, NewErrorValuef("Too few arguments, expected %d, got %d", len(to), len(args))
  244. }
  245. i:= 0
  246. for ; i < len(to) ; i ++ {
  247. fromElt := args[i]
  248. toElt := to[i]
  249. err := fromElt.Convert(toElt)
  250. if err != nil {
  251. return nil, err
  252. }
  253. }
  254. rest := args[i:len(args)]
  255. return ListFromList(rest), nil
  256. }
  257. /* Helpers to easily convert Muesli values from "normal" Go values. */
  258. func To(from interface{}) Value {
  259. switch val := from.(type) {
  260. case string:
  261. return StringValue(val)
  262. case int8:
  263. return IntValue(val)
  264. case int16:
  265. return IntValue(val)
  266. case int32:
  267. return IntValue(val)
  268. case int64:
  269. return IntValue(val)
  270. case int:
  271. return IntValue(val)
  272. case bool:
  273. return BoolValue(val)
  274. case float32:
  275. return FloatValue(val)
  276. case float64:
  277. return FloatValue(val)
  278. case error:
  279. return ErrorValue{val}
  280. case Value:
  281. return val
  282. default:
  283. return NewErrorValuef("Cannot convert value %v", from)
  284. }
  285. }
  286. func ListTo(froms ...interface{}) []Value {
  287. list := make([]Value, 0)
  288. for _, from := range froms {
  289. val := To(from)
  290. list = append(list, val)
  291. }
  292. return list
  293. }
  294. func ListFrom(froms []Value, tos ...interface{}) error {
  295. for i, from := range froms {
  296. if i >= len(tos) {
  297. break
  298. }
  299. err := From(from, tos[i])
  300. if err != nil {
  301. return err
  302. }
  303. }
  304. return nil
  305. }
  306. func ListFromList(froms []Value) []interface{} {
  307. res := make([]interface{}, len(froms))
  308. for i, from := range froms {
  309. res[i] = from
  310. }
  311. return res
  312. }