list.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package common
  2. import (
  3. "encoding/json"
  4. "reflect"
  5. "sync"
  6. )
  7. // The list type is an anonymous slice handler which can be used
  8. // for containing any slice type to use in an environment which
  9. // does not support slice types (e.g., JavaScript, QML)
  10. type List struct {
  11. mut sync.Mutex
  12. val interface{}
  13. list reflect.Value
  14. Length int
  15. }
  16. // Initialise a new list. Panics if non-slice type is given.
  17. func NewList(t interface{}) *List {
  18. list := reflect.ValueOf(t)
  19. if list.Kind() != reflect.Slice {
  20. panic("list container initialized with a non-slice type")
  21. }
  22. return &List{sync.Mutex{}, t, list, list.Len()}
  23. }
  24. func EmptyList() *List {
  25. return NewList([]interface{}{})
  26. }
  27. // Get N element from the embedded slice. Returns nil if OOB.
  28. func (self *List) Get(i int) interface{} {
  29. if self.list.Len() > i {
  30. self.mut.Lock()
  31. defer self.mut.Unlock()
  32. i := self.list.Index(i).Interface()
  33. return i
  34. }
  35. return nil
  36. }
  37. func (self *List) GetAsJson(i int) interface{} {
  38. e := self.Get(i)
  39. r, _ := json.Marshal(e)
  40. return string(r)
  41. }
  42. // Appends value at the end of the slice. Panics when incompatible value
  43. // is given.
  44. func (self *List) Append(v interface{}) {
  45. self.mut.Lock()
  46. defer self.mut.Unlock()
  47. self.list = reflect.Append(self.list, reflect.ValueOf(v))
  48. self.Length = self.list.Len()
  49. }
  50. // Returns the underlying slice as interface.
  51. func (self *List) Interface() interface{} {
  52. return self.list.Interface()
  53. }
  54. // For JavaScript <3
  55. func (self *List) ToJSON() string {
  56. // make(T, 0) != nil
  57. list := make([]interface{}, 0)
  58. for i := 0; i < self.Length; i++ {
  59. list = append(list, self.Get(i))
  60. }
  61. data, _ := json.Marshal(list)
  62. return string(data)
  63. }