formspec-editor/json.lua

94 lines
2.2 KiB
Lua

local js = require 'js'
local JSON = js.global.JSON
local null = js.null
json = {}
-- Recursively convert JavaScript objects to tables.
local function object_to_table(obj, nullvalue)
if obj == null then
return nullvalue
elseif type(obj) == 'number' then
-- Cast to integer if possible
local i = math.floor(obj)
if i == obj then return i end
return obj
elseif type(obj) ~= 'userdata' then
return obj
end
local res = {}
local array = js.global.Array:isArray(obj)
if array then obj:unshift(null) end
for k, v in (array and ipairs or pairs)(obj) do
res[k] = object_to_table(v, nullvalue)
end
return res
end
local function table_to_object(table)
local array = true
for k, v in pairs(table) do
if type(k) ~= 'number' then
array = false
break
end
end
if array then
local res = js.global:Array()
for _, elem in ipairs(table) do
if type(elem) == 'table' then
elem = table_to_object(elem)
end
res:push(elem)
end
return res
else
local res = js.global:Object()
for k, v in pairs(table) do
if type(v) == 'table' then
v = table_to_object(v)
end
res[k] = v
end
return res
end
end
-- Alias for JSON:parse so pcall can call it.
local function raw_parse(json, nullvalue)
local obj = JSON:parse(json)
return object_to_table(obj, nullvalue)
end
function json.loads(json, nullvalue)
local success, result = pcall(raw_parse, json, nullvalue)
if success then
return result, nil
else
return nil, result
end
end
json.loads = raw_parse
-- Another alias
local function raw_write(data, styled)
if styled then styled = 4 else styled = nil end
return JSON:stringify(data, nil, styled)
end
-- The un-parsing is was going to be done entirely in JavaScript, but lua.
function json.dumps(data, styled)
if type(data) == 'table' then
data = table_to_object(data)
end
local success, result = pcall(raw_write, data, styled)
if success then
return result, nil
else
return nil, result
end
end