[modified] moved tablex.stringify to stringx.pretty

This commit is contained in:
Max Cahill 2020-04-17 10:45:15 +10:00
parent 26acf1752d
commit e75147ec77
2 changed files with 59 additions and 44 deletions

View File

@ -8,15 +8,24 @@ local stringx = setmetatable({}, {
--split a string on a delimiter into an ordered table --split a string on a delimiter into an ordered table
function stringx:split(delim) function stringx:split(delim)
--try to create as little garbage as possible! --we try to create as little garbage as possible!
--one table to contain the result, plus the split strings should be all we need --only one table to contain the result, plus the split strings.
--as such we work with the bytes underlying the string, as string.find is not compiled on older luajit :) --so we do two passes, and work with the bytes underlying the string
--partly because string.find is not compiled on older luajit :)
local res = {}
local length = self:len() local length = self:len()
-- --
local delim_length = delim:len() local delim_length = delim:len()
--empty delim? split to individual characters
if delim_length == 0 then
for i = 1, length do
table.insert(res, self:sub(i, i))
end
return res
end
local delim_start = delim:byte(1) local delim_start = delim:byte(1)
--iterate through and collect split sites --pass 1
local res = {} --collect split sites
local i = 1 local i = 1
while i <= length do while i <= length do
--scan for delimiter --scan for delimiter
@ -38,7 +47,8 @@ function stringx:split(delim)
i = i + 1 i = i + 1
end end
end end
--re-iterate, collecting substrings --pass 2
--collect substrings
i = 1 i = 1
for si, j in ipairs(res) do for si, j in ipairs(res) do
res[si] = self:sub(i, j-1) res[si] = self:sub(i, j-1)
@ -50,4 +60,47 @@ function stringx:split(delim)
return res return res
end end
--turn input into a vaguely easy to read string
--(which is also able to be parsed by lua in many cases)
--todo: multi-line for big tables
--todo: support self-referential tables at least without crashing :)
function stringx.pretty(input)
--if the input is not a table, or it has a tostring metamethod
--then we can just use tostring
local mt = getmetatable(input)
if type(input) ~= "table" or mt and mt.__tostring then
local s = tostring(input)
--quote strings
if type(input) == "string" then
s = '"' .. s .. '"'
end
return s
end
--otherwise, we've got to build up a table representation
--collate into member chunks
local chunks = {}
--(tracking for already-seen elements from ipairs)
local seen = {}
--sequential part first
--(in practice, pairs already does this, but the order isn't guaranteed)
for i, v in ipairs(input) do
seen[i] = true
table.insert(chunks, stringx.pretty(v))
end
--non sequential follows
for k, v in pairs(input) do
if not seen[k] then
--encapsulate anything that's not a string
--todo: also keywords
if type(k) ~= "string" then
k = "[" .. tostring(k) .. "]"
end
table.insert(chunks, k .. " = " .. stringx.pretty(v))
end
end
return "{" .. table.concat(chunks, ", ") .. "}"
end
return stringx return stringx

View File

@ -269,44 +269,6 @@ function tablex.overlay(to, from)
return to return to
end end
--turn a table into a vaguely easy to read string
--which is also able to be parsed by lua in most cases
function tablex.stringify(t)
--if the input is not a table, or it has a tostring metamethod
--just use tostring
local mt = getmetatable(t)
if type(t) ~= "table" or mt and mt.__tostring then
local s = tostring(t)
--quote strings
if type(t) == "string" then
s = '"' .. s .. '"'
end
return s
end
--otherwise, collate into member chunks
local chunks = {}
--(tracking for already-seen elements from ipairs)
local seen = {}
--sequential part first
for i, v in ipairs(t) do
seen[i] = true
table.insert(chunks, tablex.stringify(v))
end
--non sequential follows
for k, v in pairs(t) do
if not seen[k] then
--encapsulate anything that's not a string
--todo: also keywords
if type(k) ~= "string" then
k = "[" .. tostring(k) .. "]"
end
table.insert(chunks, k .. " = " .. tablex.stringify(v))
end
end
return "{" .. table.concat(chunks, ", ") .. "}"
end
--faster unpacking for known-length tables up to 8 --faster unpacking for known-length tables up to 8
--gets around nyi in luajit --gets around nyi in luajit
--note: you can use a larger unpack than you need as the rest --note: you can use a larger unpack than you need as the rest