1
0
Fork 0
mirror of https://github.com/notwa/mm synced 2024-05-05 08:33:23 -07:00
mm/asm/serialize.lua

77 lines
1.9 KiB
Lua

-- it's simple, dumb, unsafe, incomplete, and it gets the damn job done
local type = type
local extra = require "extra"
local opairs = extra.opairs
local tostring = tostring
local open = io.open
local strfmt = string.format
local strrep = string.rep
local function kill_bom(s)
if #s >= 3 and s:byte(1)==0xEF and s:byte(2)==0xBB and s:byte(3)==0xBF then
return s:sub(4)
end
return s
end
local function sanitize(v)
local force = type(v) == 'string' and v:sub(1, 1):match('%d')
force = force and true or false
return type(v) == 'string' and strfmt('%q', v) or tostring(v), force
end
local function _serialize(value, writer, level)
level = level or 1
if type(value) == 'table' then
local indent = strrep('\t', level)
writer('{\n')
for key,value in opairs(value) do
local sane, force = sanitize(key)
local keyval = (sane == '"'..key..'"' and not force) and key or '['..sane..']'
writer(indent..keyval..' = ')
_serialize(value, writer, level + 1)
writer(',\n')
end
writer(strrep('\t', level - 1)..'}')
else
local sane, force = sanitize(value)
writer(sane)
end
end
local function _deserialize(script)
local f = loadstring(kill_bom(script))
if f ~= nil then
return f()
else
print('WARNING: no function to deserialize with')
return nil
end
end
local function serialize(path, value)
local file = open(path, 'w')
if not file then return end
file:write("return ")
_serialize(value, function(...)
file:write(...)
end)
file:write("\n")
file:close()
end
local function deserialize(path)
local file = open(path, 'r')
if not file then return end
local script = file:read('*a')
local value = _deserialize(script)
file:close()
return value
end
return {
serialize = serialize,
deserialize = deserialize,
}