From d9e75d7c47282de6a1781be47aa2365e1e6b6143 Mon Sep 17 00:00:00 2001 From: Chick Chicky <91527355+ChickChicky@users.noreply.github.com> Date: Sun, 8 May 2022 11:53:02 +0200 Subject: [PATCH] Added parse_empty_array to textutils.unserialiseJSON (#1092) Fixes #1089. --- .../computercraft/lua/rom/apis/textutils.lua | 72 ++++++++++++------- .../test-rom/spec/apis/textutils_spec.lua | 11 ++- 2 files changed, 55 insertions(+), 28 deletions(-) diff --git a/src/main/resources/data/computercraft/lua/rom/apis/textutils.lua b/src/main/resources/data/computercraft/lua/rom/apis/textutils.lua index bd5d2f606..e5bc459f5 100644 --- a/src/main/resources/data/computercraft/lua/rom/apis/textutils.lua +++ b/src/main/resources/data/computercraft/lua/rom/apis/textutils.lua @@ -631,7 +631,13 @@ do end if c == "" then return expected(pos, c, "']'") end - if c == "]" then return empty_json_array, pos + 1 end + if c == "]" then + if opts.parse_empty_array ~= false then + return empty_json_array, pos + 1 + else + return {}, pos + 1 + end + end while true do n, arr[n], pos = n + 1, decode_impl(str, pos, opts) @@ -652,37 +658,51 @@ do error_at(pos, "Unexpected character %q.", c) end - --- Converts a serialised JSON string back into a reassembled Lua object. - -- - -- This may be used with @{textutils.serializeJSON}, or when communicating - -- with command blocks or web APIs. - -- - -- If a `null` value is encountered, it is converted into @{textutils.json_null}. - -- If an empty array is encountered, it is converted into @{textutils.empty_json_array}. - -- - -- @tparam string s The serialised string to deserialise. - -- @tparam[opt] { nbt_style? = boolean, parse_null? = boolean } options - -- Options which control how this JSON object is parsed. - -- - -- - `nbt_style`: When true, this will accept [stringified NBT][nbt] strings, - -- as produced by many commands. - -- - `parse_null`: When true, `null` will be parsed as @{json_null}, rather - -- than `nil`. - -- - -- [nbt]: https://minecraft.gamepedia.com/NBT_format - -- @return[1] The deserialised object - -- @treturn[2] nil If the object could not be deserialised. - -- @treturn string A message describing why the JSON string is invalid. - -- @since 1.87.0 - -- @see textutils.json_null Use to serialize a JSON `null` value. - -- @see textutils.empty_json_array Use to serialize a JSON empty array. + --[[- Converts a serialised JSON string back into a reassembled Lua object. + + This may be used with @{textutils.serializeJSON}, or when communicating + with command blocks or web APIs. + + If a `null` value is encountered, it is converted into `nil`. It can be converted + into @{textutils.json_null} with the `parse_null` option. + + If an empty array is encountered, it is converted into @{textutils.empty_json_array}. + It can be converted into a new empty table with the `parse_empty_array` option. + + @tparam string s The serialised string to deserialise. + @tparam[opt] { nbt_style? = boolean, parse_null? = boolean, parse_empty_array? = boolean } options + Options which control how this JSON object is parsed. + + - `nbt_style`: When true, this will accept [stringified NBT][nbt] strings, + as produced by many commands. + - `parse_null`: When true, `null` will be parsed as @{json_null}, rather than + `nil`. + - `parse_empty_array`: When false, empty arrays will be parsed as a new table. + By default (or when this value is true), they are parsed as @{empty_json_array}. + + [nbt]: https://minecraft.gamepedia.com/NBT_format + @return[1] The deserialised object + @treturn[2] nil If the object could not be deserialised. + @treturn string A message describing why the JSON string is invalid. + @since 1.87.0 + @see textutils.json_null Use to serialize a JSON `null` value. + @see textutils.empty_json_array Use to serialize a JSON empty array. + @usage Unserialise a basic JSON object + + textutils.unserialiseJSON('{"name": "Steve", "age": null}') + + @usage Unserialise a basic JSON object, returning null values as @{json_null}. + + textutils.unserialiseJSON('{"name": "Steve", "age": null}', { parse_null = true }) + ]] unserialise_json = function(s, options) expect(1, s, "string") expect(2, options, "table", "nil") if options then field(options, "nbt_style", "boolean", "nil") - field(options, "nbt_style", "boolean", "nil") + field(options, "parse_null", "boolean", "nil") + field(options, "parse_empty_array", "boolean", "nil") else options = {} end diff --git a/src/test/resources/test-rom/spec/apis/textutils_spec.lua b/src/test/resources/test-rom/spec/apis/textutils_spec.lua index 71f426366..1bf3d7402 100644 --- a/src/test/resources/test-rom/spec/apis/textutils_spec.lua +++ b/src/test/resources/test-rom/spec/apis/textutils_spec.lua @@ -177,8 +177,15 @@ describe("The textutils library", function() expect(textutils.unserializeJSON("null", { parse_null = false })):eq(nil) end) - it("an empty array", function() - expect(textutils.unserializeJSON("[]", { parse_null = false })):eq(textutils.empty_json_array) + it("an empty array when parse_empty_array is true", function() + expect(textutils.unserializeJSON("[]")):eq(textutils.empty_json_array) + expect(textutils.unserializeJSON("[]", { parse_empty_array = true })):eq(textutils.empty_json_array) + end) + + it("an empty array when parse_empty_array is false", function() + expect(textutils.unserializeJSON("[]", { parse_empty_array = false })) + :ne(textutils.empty_json_array) + :same({}) end) it("basic objects", function()