From 08321754de482e91d18883bc9d04fde88d90f6ae Mon Sep 17 00:00:00 2001 From: Harry Bagdi Date: Fri, 3 Dec 2021 09:14:30 -0800 Subject: [PATCH 1/3] feat: make gopher-json a go module --- go.mod | 5 +++++ go.sum | 2 ++ 2 files changed, 7 insertions(+) create mode 100644 go.mod create mode 100644 go.sum diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..4f10a30 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/layeh/gopher-json + +go 1.19 + +require github.com/yuin/gopher-lua v0.0.0-20221210110428-332342483e3f diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..b744d95 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/yuin/gopher-lua v0.0.0-20221210110428-332342483e3f h1:wihIB0V/mGpVYrL8I7n/WxVqWnP07CBXZ5uCgxUP1tI= +github.com/yuin/gopher-lua v0.0.0-20221210110428-332342483e3f/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= From 801200f24d0a2493018a6b199523308a87063e1b Mon Sep 17 00:00:00 2001 From: Harry Bagdi Date: Fri, 3 Dec 2021 09:15:03 -0800 Subject: [PATCH 2/3] feat: marshal userdata as json 'null' --- json.go | 5 ++++- json_test.go | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/json.go b/json.go index c34af2d..c8a8148 100644 --- a/json.go +++ b/json.go @@ -4,7 +4,7 @@ import ( "encoding/json" "errors" - "github.com/yuin/gopher-lua" + lua "github.com/yuin/gopher-lua" ) // Preload adds json to the given Lua state's package.preload table. After it @@ -131,6 +131,9 @@ func (j jsonValue) MarshalJSON() (data []byte, err error) { default: err = errInvalidKeys } + case *lua.LUserData: + data, err = json.Marshal(nil) + return default: err = invalidTypeError(j.LValue.Type()) } diff --git a/json_test.go b/json_test.go index fbd627d..7d4fea6 100644 --- a/json_test.go +++ b/json_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/yuin/gopher-lua" + lua "github.com/yuin/gopher-lua" ) func TestSimple(t *testing.T) { @@ -62,6 +62,8 @@ func TestSimple(t *testing.T) { a[i] = i end assert(json.encode(a) == "[1,2,3,4,5]") + + assert(json.encode(json) == nil) ` s := lua.NewState() defer s.Close() From 64015758f4ba8b3f0a102c593027a8d4e021f1d1 Mon Sep 17 00:00:00 2001 From: Fero <6863207+mikefero@users.noreply.github.com> Date: Fri, 25 Mar 2022 12:52:50 -0400 Subject: [PATCH 3/3] feat: allow encoding of sparse arrays This fix allows for sparse array and converts the key (which is the index in this case) into part of the JSON encoded output. --- json.go | 9 ++++---- json_test.go | 60 +++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/json.go b/json.go index c8a8148..0ee7117 100644 --- a/json.go +++ b/json.go @@ -3,6 +3,7 @@ package json import ( "encoding/json" "errors" + "fmt" lua "github.com/yuin/gopher-lua" ) @@ -56,7 +57,6 @@ func apiEncode(L *lua.LState) int { var ( errNested = errors.New("cannot encode recursively nested tables to JSON") - errSparseArray = errors.New("cannot encode sparse array") errInvalidKeys = errors.New("cannot encode mixed or invalid key types") ) @@ -109,10 +109,11 @@ func (j jsonValue) MarshalJSON() (data []byte, err error) { return } if expectedKey != key { - err = errSparseArray - return + errValue := lua.LString(fmt.Sprintf("[%s] = %s", key.String(), value.String())) + arr = append(arr, jsonValue{errValue, j.visited}) + } else { + arr = append(arr, jsonValue{value, j.visited}) } - arr = append(arr, jsonValue{value, j.visited}) expectedKey++ key, value = converted.Next(key) } diff --git a/json_test.go b/json_test.go index 7d4fea6..a164bc9 100644 --- a/json_test.go +++ b/json_test.go @@ -2,6 +2,7 @@ package json import ( "encoding/json" + "fmt" "testing" lua "github.com/yuin/gopher-lua" @@ -21,9 +22,6 @@ func TestSimple(t *testing.T) { assert(json.encode({}) == "[]") assert(json.encode({1, 2, 3}) == "[1,2,3]") - local _, err = json.encode({1, 2, [10] = 3}) - assert(string.find(err, "sparse array")) - local _, err = json.encode({1, 2, 3, name = "Tim"}) assert(string.find(err, "mixed or invalid key types")) @@ -99,3 +97,59 @@ func TestDecodeValue_jsonNumber(t *testing.T) { t.Fatalf("expecting LString, got %T", v) } } + +func TestEncode_SparseArray(t *testing.T) { + tests := []struct { + table string + expected string + }{ + { + table: `{ + 1, + 2, + [10] = 3 + }`, + expected: `[1,2,"[10] = 3"]`, + }, + { + table: `{ + nested = { + [37] = "index 37" + } + }`, + expected: `{"nested":["[37] = index 37"]}`, + }, + { + table: `{ + nested = { + "index 1", + [37] = "index 37" + } + }`, + expected: `{"nested":["index 1","[37] = index 37"]}`, + }, + { + table: `{ + nested = { + "index 1", + [37] = "index 37" + } + }`, + expected: `{"nested":["index 1","[37] = index 37"]}`, + }, + } + + for _, test := range tests { + s := lua.NewState() + defer s.Close() + Preload(s) + + luaScript := fmt.Sprintf(` + local json = require("json") + local t = %s + assert(json.encode(t) == '%s')`, test.table, test.expected) + if err := s.DoString(luaScript); err != nil { + t.Error(err) + } + } +}