mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-08-03 20:33:58 +00:00
Add some options for textutils.serialize (#664)
This commit is contained in:
parent
e0e194099c
commit
38335ca187
@ -262,41 +262,48 @@ local g_tLuaKeywords = {
|
|||||||
["while"] = true,
|
["while"] = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
local function serializeImpl(t, tTracking, sIndent)
|
local function serialize_impl(t, tracking, indent, opts)
|
||||||
local sType = type(t)
|
local sType = type(t)
|
||||||
if sType == "table" then
|
if sType == "table" then
|
||||||
if tTracking[t] ~= nil then
|
if tracking[t] ~= nil then
|
||||||
error("Cannot serialize table with recursive entries", 0)
|
error("Cannot serialize table with recursive entries", 0)
|
||||||
end
|
end
|
||||||
tTracking[t] = true
|
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 sResult = "{\n"
|
local open, sub_indent, open_key, close_key, equal, comma = "{\n", indent .. " ", "[ ", " ] = ", " = ", ",\n"
|
||||||
local sSubIndent = sIndent .. " "
|
if opts.compact then
|
||||||
local tSeen = {}
|
open, sub_indent, open_key, close_key, equal, comma = "{", "", "[", "]=", "=", ","
|
||||||
|
end
|
||||||
|
|
||||||
|
result = open
|
||||||
|
local seen_keys = {}
|
||||||
for k, v in ipairs(t) do
|
for k, v in ipairs(t) do
|
||||||
tSeen[k] = true
|
seen_keys[k] = true
|
||||||
sResult = sResult .. sSubIndent .. serializeImpl(v, tTracking, sSubIndent) .. ",\n"
|
result = result .. sub_indent .. serialize_impl(v, tracking, sub_indent, opts) .. comma
|
||||||
end
|
end
|
||||||
for k, v in pairs(t) do
|
for k, v in pairs(t) do
|
||||||
if not tSeen[k] then
|
if not seen_keys[k] then
|
||||||
local sEntry
|
local sEntry
|
||||||
if type(k) == "string" and not g_tLuaKeywords[k] and string.match(k, "^[%a_][%a%d_]*$") then
|
if type(k) == "string" and not g_tLuaKeywords[k] and string.match(k, "^[%a_][%a%d_]*$") then
|
||||||
sEntry = k .. " = " .. serializeImpl(v, tTracking, sSubIndent) .. ",\n"
|
sEntry = k .. equal .. serialize_impl(v, tracking, sub_indent, opts) .. comma
|
||||||
else
|
else
|
||||||
sEntry = "[ " .. serializeImpl(k, tTracking, sSubIndent) .. " ] = " .. serializeImpl(v, tTracking, sSubIndent) .. ",\n"
|
sEntry = open_key .. serialize_impl(k, tracking, sub_indent, opts) .. close_key .. serialize_impl(v, tracking, sub_indent, opts) .. comma
|
||||||
end
|
end
|
||||||
sResult = sResult .. sSubIndent .. sEntry
|
result = result .. sub_indent .. sEntry
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
sResult = sResult .. sIndent .. "}"
|
result = result .. indent .. "}"
|
||||||
return sResult
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if opts.allow_repetitions then tracking[t] = nil end
|
||||||
|
return result
|
||||||
|
|
||||||
elseif sType == "string" then
|
elseif sType == "string" then
|
||||||
return string.format("%q", t)
|
return string.format("%q", t)
|
||||||
|
|
||||||
@ -645,17 +652,43 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Convert a Lua object into a textual representation, suitable for
|
--[[- Convert a Lua object into a textual representation, suitable for
|
||||||
-- saving in a file or pretty-printing.
|
saving in a file or pretty-printing.
|
||||||
--
|
|
||||||
-- @param t The object to serialise
|
@param t The object to serialise
|
||||||
-- @treturn string The serialised representation
|
@tparam { compact? = boolean, allow_repetitions? = boolean } opts Options for serialisation.
|
||||||
-- @throws If the object contains a value which cannot be
|
- `compact`: Do not emit indentation and other whitespace between terms.
|
||||||
-- serialised. This includes functions and tables which appear multiple
|
- `allow_repetitions`: Relax the check for recursive tables, allowing them to appear multiple
|
||||||
-- times.
|
times (as long as tables do not appear inside themselves).
|
||||||
function serialize(t)
|
|
||||||
|
@treturn string The serialised representation
|
||||||
|
@throws If the object contains a value which cannot be
|
||||||
|
serialised. This includes functions and tables which appear multiple
|
||||||
|
times.
|
||||||
|
@see cc.pretty.pretty An alternative way to display a table, often more suitable for
|
||||||
|
pretty printing.
|
||||||
|
@usage Pretty print a basic table.
|
||||||
|
|
||||||
|
textutils.serialise({ 1, 2, 3, a = 1, ["another key"] = { true } })
|
||||||
|
|
||||||
|
@usage Demonstrates some of the other options
|
||||||
|
|
||||||
|
local tbl = { 1, 2, 3 }
|
||||||
|
print(textutils.serialize({ tbl, tbl }, { allow_repetitions = true }))
|
||||||
|
|
||||||
|
print(textutils.serialize(tbl, { compact = true }))
|
||||||
|
]]
|
||||||
|
function serialize(t, opts)
|
||||||
local tTracking = {}
|
local tTracking = {}
|
||||||
return serializeImpl(t, tTracking, "")
|
expect(2, opts, "table", "nil")
|
||||||
|
|
||||||
|
if opts then
|
||||||
|
field(opts, "compact", "boolean", "nil")
|
||||||
|
field(opts, "allow_repetitions", "boolean", "nil")
|
||||||
|
else
|
||||||
|
opts = {}
|
||||||
|
end
|
||||||
|
return serialize_impl(t, tTracking, "", opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
serialise = serialize -- GB version
|
serialise = serialize -- GB version
|
||||||
|
@ -62,6 +62,42 @@ describe("The textutils library", function()
|
|||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
describe("textutils.serialise", function()
|
||||||
|
it("serialises basic tables", function()
|
||||||
|
expect(textutils.serialise({ 1, 2, 3, a = 1, b = {} }))
|
||||||
|
:eq("{\n 1,\n 2,\n 3,\n a = 1,\n b = {},\n}")
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("fails on recursive tables", function()
|
||||||
|
local rep = {}
|
||||||
|
expect.error(textutils.serialise, { rep, rep }):eq("Cannot serialize table with recursive entries")
|
||||||
|
|
||||||
|
local rep2 = { 1 }
|
||||||
|
expect.error(textutils.serialise, { rep2, rep2 }):eq("Cannot serialize table with recursive entries")
|
||||||
|
|
||||||
|
local recurse = {}
|
||||||
|
recurse[1] = recurse
|
||||||
|
expect.error(textutils.serialise, recurse):eq("Cannot serialize table with recursive entries")
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("can allow repeated tables", function()
|
||||||
|
local rep = {}
|
||||||
|
expect(textutils.serialise({ rep, rep }, { allow_repetitions = true })):eq("{\n {},\n {},\n}")
|
||||||
|
|
||||||
|
local rep2 = { 1 }
|
||||||
|
expect(textutils.serialise({ rep2, rep2 }, { allow_repetitions = true })):eq("{\n {\n 1,\n },\n {\n 1,\n },\n}")
|
||||||
|
|
||||||
|
local recurse = {}
|
||||||
|
recurse[1] = recurse
|
||||||
|
expect.error(textutils.serialise, recurse, { allow_repetitions = true }):eq("Cannot serialize table with recursive entries")
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("can emit in a compact form", function()
|
||||||
|
expect(textutils.serialise({ 1, 2, 3, a = 1, [false] = {} }, { compact = true }))
|
||||||
|
:eq("{1,2,3,a=1,[false]={},}")
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
describe("textutils.unserialise", function()
|
describe("textutils.unserialise", function()
|
||||||
it("validates arguments", function()
|
it("validates arguments", function()
|
||||||
textutils.unserialise("")
|
textutils.unserialise("")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user