mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-10-31 13:42:59 +00:00 
			
		
		
		
	| @@ -448,20 +448,25 @@ do | |||||||
|     end |     end | ||||||
| end | end | ||||||
|  |  | ||||||
| local function serializeJSONImpl(t, tTracking, options) | local function serializeJSONImpl(t, tracking, options) | ||||||
|     local sType = type(t) |     local sType = type(t) | ||||||
|     if t == empty_json_array then return "[]" |     if t == empty_json_array then return "[]" | ||||||
|     elseif t == json_null then return "null" |     elseif t == json_null then return "null" | ||||||
|  |  | ||||||
|     elseif sType == "table" then |     elseif sType == "table" then | ||||||
|         if tTracking[t] ~= nil then |         if tracking[t] ~= nil then | ||||||
|  |             if tracking[t] == false then | ||||||
|  |                 error("Cannot serialize table with repeated entries", 0) | ||||||
|  |             else | ||||||
|                 error("Cannot serialize table with recursive entries", 0) |                 error("Cannot serialize table with recursive entries", 0) | ||||||
|             end |             end | ||||||
|         tTracking[t] = true |         end | ||||||
|  |         tracking[t] = true | ||||||
|  |  | ||||||
|  |         local result | ||||||
|         if next(t) == nil then |         if next(t) == nil then | ||||||
|             -- Empty tables are simple |             -- Empty tables are simple | ||||||
|             return "{}" |             result = "{}" | ||||||
|         else |         else | ||||||
|             -- Other tables take more work |             -- Other tables take more work | ||||||
|             local sObjectResult = "{" |             local sObjectResult = "{" | ||||||
| @@ -469,14 +474,14 @@ local function serializeJSONImpl(t, tTracking, options) | |||||||
|             local nObjectSize = 0 |             local nObjectSize = 0 | ||||||
|             local nArraySize = 0 |             local nArraySize = 0 | ||||||
|             local largestArrayIndex = 0 |             local largestArrayIndex = 0 | ||||||
|             local bNBTStyle = options and options.nbt_style |             local bNBTStyle = options.nbt_style | ||||||
|             for k, v in pairs(t) do |             for k, v in pairs(t) do | ||||||
|                 if type(k) == "string" then |                 if type(k) == "string" then | ||||||
|                     local sEntry |                     local sEntry | ||||||
|                     if bNBTStyle then |                     if bNBTStyle then | ||||||
|                         sEntry = tostring(k) .. ":" .. serializeJSONImpl(v, tTracking, options) |                         sEntry = tostring(k) .. ":" .. serializeJSONImpl(v, tracking, options) | ||||||
|                     else |                     else | ||||||
|                         sEntry = serializeJSONString(k, options) .. ":" .. serializeJSONImpl(v, tTracking, options) |                         sEntry = serializeJSONString(k, options) .. ":" .. serializeJSONImpl(v, tracking, options) | ||||||
|                     end |                     end | ||||||
|                     if nObjectSize == 0 then |                     if nObjectSize == 0 then | ||||||
|                         sObjectResult = sObjectResult .. sEntry |                         sObjectResult = sObjectResult .. sEntry | ||||||
| @@ -493,7 +498,7 @@ local function serializeJSONImpl(t, tTracking, options) | |||||||
|                 if t[k] == nil then --if the array is nil at index k the value is "null" as to keep the unused indexes in between used ones. |                 if t[k] == nil then --if the array is nil at index k the value is "null" as to keep the unused indexes in between used ones. | ||||||
|                     sEntry = "null" |                     sEntry = "null" | ||||||
|                 else -- if the array index does not point to a nil we serialise it's content. |                 else -- if the array index does not point to a nil we serialise it's content. | ||||||
|                     sEntry = serializeJSONImpl(t[k], tTracking, options) |                     sEntry = serializeJSONImpl(t[k], tracking, options) | ||||||
|                 end |                 end | ||||||
|                 if nArraySize == 0 then |                 if nArraySize == 0 then | ||||||
|                     sArrayResult = sArrayResult .. sEntry |                     sArrayResult = sArrayResult .. sEntry | ||||||
| @@ -505,12 +510,19 @@ local function serializeJSONImpl(t, tTracking, options) | |||||||
|             sObjectResult = sObjectResult .. "}" |             sObjectResult = sObjectResult .. "}" | ||||||
|             sArrayResult = sArrayResult .. "]" |             sArrayResult = sArrayResult .. "]" | ||||||
|             if nObjectSize > 0 or nArraySize == 0 then |             if nObjectSize > 0 or nArraySize == 0 then | ||||||
|                 return sObjectResult |                 result = sObjectResult | ||||||
|             else |             else | ||||||
|                 return sArrayResult |                 result = sArrayResult | ||||||
|             end |             end | ||||||
|         end |         end | ||||||
|  |  | ||||||
|  |         if options.allow_repetitions then | ||||||
|  |             tracking[t] = nil | ||||||
|  |         else | ||||||
|  |             tracking[t] = false | ||||||
|  |         end | ||||||
|  |         return result | ||||||
|  |  | ||||||
|     elseif sType == "string" then |     elseif sType == "string" then | ||||||
|         return serializeJSONString(t, options) |         return serializeJSONString(t, options) | ||||||
|  |  | ||||||
| @@ -844,10 +856,16 @@ This is largely intended for interacting with various functions from the | |||||||
|  |  | ||||||
| @param[1] t The value to serialise. Like [`textutils.serialise`], this should not | @param[1] t The value to serialise. Like [`textutils.serialise`], this should not | ||||||
| contain recursive tables or functions. | contain recursive tables or functions. | ||||||
| @tparam[1,opt] { nbt_style? = boolean, unicode_strings? = boolean } options Options for serialisation. | @tparam[1,opt] { | ||||||
|  |     nbt_style? = boolean, | ||||||
|  |     unicode_strings? = boolean, | ||||||
|  |     allow_repetitions? = boolean | ||||||
|  | } options Options for serialisation. | ||||||
|  - `nbt_style`: Whether to produce NBT-style JSON (non-quoted keys) instead of standard JSON. |  - `nbt_style`: Whether to produce NBT-style JSON (non-quoted keys) instead of standard JSON. | ||||||
|  - `unicode_strings`: Whether to treat strings as containing UTF-8 characters instead of |  - `unicode_strings`: Whether to treat strings as containing UTF-8 characters instead of | ||||||
|     using the default 8-bit character set. |     using the default 8-bit character set. | ||||||
|  |  - `allow_repetitions`: Relax the check for recursive tables, allowing them to appear multiple | ||||||
|  |    times (as long as tables do not appear inside themselves). | ||||||
|  |  | ||||||
| @param[2] t The value to serialise. Like [`textutils.serialise`], this should not | @param[2] t The value to serialise. Like [`textutils.serialise`], this should not | ||||||
| contain recursive tables or functions. | contain recursive tables or functions. | ||||||
| @@ -868,6 +886,7 @@ functions and tables which appear multiple times. | |||||||
|  |  | ||||||
| @since 1.7 | @since 1.7 | ||||||
| @changed 1.106.0 Added `options` overload and `unicode_strings` option. | @changed 1.106.0 Added `options` overload and `unicode_strings` option. | ||||||
|  | @changed 1.109.0 Added `allow_repetitions` option. | ||||||
|  |  | ||||||
| @see textutils.json_null Use to serialise a JSON `null` value. | @see textutils.json_null Use to serialise a JSON `null` value. | ||||||
| @see textutils.empty_json_array Use to serialise a JSON empty array. | @see textutils.empty_json_array Use to serialise a JSON empty array. | ||||||
| @@ -880,6 +899,9 @@ function serializeJSON(t, options) | |||||||
|     elseif type(options) == "table" then |     elseif type(options) == "table" then | ||||||
|         field(options, "nbt_style", "boolean", "nil") |         field(options, "nbt_style", "boolean", "nil") | ||||||
|         field(options, "unicode_strings", "boolean", "nil") |         field(options, "unicode_strings", "boolean", "nil") | ||||||
|  |         field(options, "allow_repetitions", "boolean", "nil") | ||||||
|  |     else | ||||||
|  |         options = {} | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     local tTracking = {} |     local tTracking = {} | ||||||
|   | |||||||
| @@ -187,6 +187,30 @@ describe("The textutils library", function() | |||||||
|             expect(textutils.serializeJSON("\u{1f62f}", { unicode_strings = true })):eq([["\uD83D\uDE2F"]]) |             expect(textutils.serializeJSON("\u{1f62f}", { unicode_strings = true })):eq([["\uD83D\uDE2F"]]) | ||||||
|             expect(textutils.serializeJSON("\\\"\u{00ff}\n\"", { unicode_strings = true })):eq('"\\\\\\"\\u00FF\\n\\""') |             expect(textutils.serializeJSON("\\\"\u{00ff}\n\"", { unicode_strings = true })):eq('"\\\\\\"\\u00FF\\n\\""') | ||||||
|         end) |         end) | ||||||
|  |  | ||||||
|  |         it("fails on recursive/repeated tables", function() | ||||||
|  |             local rep = {} | ||||||
|  |             expect.error(textutils.serialiseJSON, { rep, rep }):eq("Cannot serialize table with repeated entries") | ||||||
|  |  | ||||||
|  |             local rep2 = { 1 } | ||||||
|  |             expect.error(textutils.serialiseJSON, { rep2, rep2 }):eq("Cannot serialize table with repeated entries") | ||||||
|  |  | ||||||
|  |             local recurse = {} | ||||||
|  |             recurse[1] = recurse | ||||||
|  |             expect.error(textutils.serialiseJSON, recurse):eq("Cannot serialize table with recursive entries") | ||||||
|  |         end) | ||||||
|  |  | ||||||
|  |         it("can allow repeated tables", function() | ||||||
|  |             local rep = {} | ||||||
|  |             expect(textutils.serialiseJSON({ rep, rep }, { allow_repetitions = true })):eq("[{},{}]") | ||||||
|  |  | ||||||
|  |             local rep2 = { 1 } | ||||||
|  |             expect(textutils.serialiseJSON({ rep2, rep2 }, { allow_repetitions = true })):eq("[[1],[1]]") | ||||||
|  |  | ||||||
|  |             local recurse = {} | ||||||
|  |             recurse[1] = recurse | ||||||
|  |             expect.error(textutils.serialiseJSON, recurse, { allow_repetitions = true }):eq("Cannot serialize table with recursive entries") | ||||||
|  |         end) | ||||||
|     end) |     end) | ||||||
|  |  | ||||||
|     describe("textutils.unserializeJSON", function() |     describe("textutils.unserializeJSON", function() | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jonathan Coates
					Jonathan Coates