Improve `common.serialize` (#1640)

* Make `common.serialize` more locale-independent

* Handle inf/nan numbers in `common.serialize`
This commit is contained in:
Guldoman 2023-10-18 06:45:52 +02:00 committed by George Sokianos
parent 1669409610
commit 9612f20685
1 changed files with 11 additions and 2 deletions

View File

@ -378,12 +378,15 @@ function common.bench(name, fn, ...)
return res return res
end end
-- From gvx/Ser
local oddvals = {[tostring(1/0)] = "1/0", [tostring(-1/0)] = "-1/0", [tostring(-(0/0))] = "-(0/0)", [tostring(0/0)] = "0/0"}
local function serialize(val, pretty, indent_str, escape, sort, limit, level) local function serialize(val, pretty, indent_str, escape, sort, limit, level)
local space = pretty and " " or "" local space = pretty and " " or ""
local indent = pretty and string.rep(indent_str, level) or "" local indent = pretty and string.rep(indent_str, level) or ""
local newline = pretty and "\n" or "" local newline = pretty and "\n" or ""
if type(val) == "string" then local ty = type(val)
if ty == "string" then
local out = string.format("%q", val) local out = string.format("%q", val)
if escape then if escape then
out = string.gsub(out, "\\\n", "\\n") out = string.gsub(out, "\\\n", "\\n")
@ -395,7 +398,7 @@ local function serialize(val, pretty, indent_str, escape, sort, limit, level)
out = string.gsub(out, "\\13", "\\r") out = string.gsub(out, "\\13", "\\r")
end end
return out return out
elseif type(val) == "table" then elseif ty == "table" then
-- early exit -- early exit
if level >= limit then return tostring(val) end if level >= limit then return tostring(val) end
local next_indent = pretty and (indent .. indent_str) or "" local next_indent = pretty and (indent .. indent_str) or ""
@ -410,6 +413,12 @@ local function serialize(val, pretty, indent_str, escape, sort, limit, level)
if sort then table.sort(t) end if sort then table.sort(t) end
return "{" .. newline .. table.concat(t, "," .. newline) .. newline .. indent .. "}" return "{" .. newline .. table.concat(t, "," .. newline) .. newline .. indent .. "}"
end end
if ty == "number" then
-- tostring is locale-dependent, so we need to replace an eventual `,` with `.`
local res, _ = tostring(val):gsub(",", ".")
-- handle inf/nan
return oddvals[res] or res
end
return tostring(val) return tostring(val)
end end