在go中使用lua示例, 基于gopher-lua!
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

127 行
2.9 KiB

4 年前
  1. package json
  2. import (
  3. "encoding/json"
  4. "errors"
  5. lua "github.com/yuin/gopher-lua"
  6. )
  7. var (
  8. errNested = errors.New("cannot encode recursively nested tables to JSON")
  9. errSparseArray = errors.New("cannot encode sparse array")
  10. errInvalidKeys = errors.New("cannot encode mixed or invalid key types")
  11. )
  12. type invalidTypeError lua.LValueType
  13. func (i invalidTypeError) Error() string {
  14. return `cannot encode ` + lua.LValueType(i).String() + ` to JSON`
  15. }
  16. type jsonValue struct {
  17. lua.LValue
  18. visited map[*lua.LTable]bool
  19. }
  20. func (j jsonValue) MarshalJSON() (data []byte, err error) {
  21. switch converted := j.LValue.(type) {
  22. case lua.LBool:
  23. data, err = json.Marshal(bool(converted))
  24. case lua.LNumber:
  25. data, err = json.Marshal(float64(converted))
  26. case *lua.LNilType:
  27. data = []byte(`null`)
  28. case lua.LString:
  29. data, err = json.Marshal(string(converted))
  30. case *lua.LTable:
  31. if j.visited[converted] {
  32. return nil, errNested
  33. }
  34. j.visited[converted] = true
  35. key, value := converted.Next(lua.LNil)
  36. switch key.Type() {
  37. case lua.LTNil: // empty table
  38. data = []byte(`[]`)
  39. case lua.LTNumber:
  40. arr := make([]jsonValue, 0, converted.Len())
  41. expectedKey := lua.LNumber(1)
  42. for key != lua.LNil {
  43. if key.Type() != lua.LTNumber {
  44. err = errInvalidKeys
  45. return
  46. }
  47. if expectedKey != key {
  48. err = errSparseArray
  49. return
  50. }
  51. arr = append(arr, jsonValue{value, j.visited})
  52. expectedKey++
  53. key, value = converted.Next(key)
  54. }
  55. data, err = json.Marshal(arr)
  56. case lua.LTString:
  57. obj := make(map[string]jsonValue)
  58. for key != lua.LNil {
  59. if key.Type() != lua.LTString {
  60. err = errInvalidKeys
  61. return
  62. }
  63. obj[key.String()] = jsonValue{value, j.visited}
  64. key, value = converted.Next(key)
  65. }
  66. data, err = json.Marshal(obj)
  67. default:
  68. err = errInvalidKeys
  69. }
  70. default:
  71. err = invalidTypeError(j.LValue.Type())
  72. }
  73. return
  74. }
  75. // ValueDecode converts the JSON encoded data to Lua values.
  76. func ValueDecode(L *lua.LState, data []byte) (lua.LValue, error) {
  77. var value interface{}
  78. err := json.Unmarshal(data, &value)
  79. if err != nil {
  80. return nil, err
  81. }
  82. return decode(L, value), nil
  83. }
  84. func decode(L *lua.LState, value interface{}) lua.LValue {
  85. switch converted := value.(type) {
  86. case bool:
  87. return lua.LBool(converted)
  88. case float64:
  89. return lua.LNumber(converted)
  90. case string:
  91. return lua.LString(converted)
  92. case []interface{}:
  93. arr := L.CreateTable(len(converted), 0)
  94. for _, item := range converted {
  95. arr.Append(decode(L, item))
  96. }
  97. return arr
  98. case map[string]interface{}:
  99. tbl := L.CreateTable(0, len(converted))
  100. for key, item := range converted {
  101. tbl.RawSetH(lua.LString(key), decode(L, item))
  102. }
  103. return tbl
  104. case nil:
  105. return lua.LNil
  106. }
  107. panic("unreachable")
  108. }
  109. // ValueEncode returns the JSON encoding of value.
  110. func ValueEncode(value lua.LValue) ([]byte, error) {
  111. return json.Marshal(jsonValue{
  112. LValue: value,
  113. visited: make(map[*lua.LTable]bool),
  114. })
  115. }