Advertisement
YellowAfterlife

Metatable serializer in Lua

Aug 16th, 2012
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 2.17 KB | None | 0 0
  1. -- serialize ~ by YellowAfterlife
  2. -- Converts value back into according Lua presentation
  3. -- Accepts strings, numbers, boolean values, and tables.
  4. -- Table values are serialized recursively, so tables linking to themselves or
  5. -- linking to other tables in "circles". Table indexes can be numbers, strings,
  6. -- and boolean values.
  7. function serialize(object, multiline, depth, name)
  8.     depth = depth or 0
  9.     if multiline == nil then multiline = true end
  10.     local padding = string.rep('    ', depth) -- can use '\t' if printing to file
  11.     local r = padding -- result string
  12.     if name then -- should start from name
  13.         r = r .. (
  14.             -- enclose in brackets if not string or not a valid identifier
  15.             -- thanks to Boolsheet from #love@irc.oftc.net for string pattern
  16.             (type(name) ~= 'string' or name:find('^([%a_][%w_]*)$') == nil)
  17.             and ('[' .. (
  18.                 (type(name) == 'string')
  19.                 and string.format('%q', name)
  20.                 or tostring(name))
  21.                 .. ']')
  22.             or tostring(name)) .. ' = '
  23.     end
  24.     if type(object) == 'table' then
  25.         r = r .. '{' .. (multiline and '\n' or ' ')
  26.         local length = 0
  27.         for i, v in ipairs(object) do
  28.             r = r .. serialize(v, multiline, multiline and (depth + 1) or 0) .. ','
  29.                 .. (multiline and '\n' or ' ')
  30.             length = i
  31.         end
  32.         for i, v in pairs(object) do
  33.             local itype = type(i) -- convert type into something easier to compare:
  34.             itype =(itype == 'number') and 1
  35.                 or (itype == 'string') and 2
  36.                 or (itype == 'boolean') and 3
  37.                 or error('Serialize: Unsupported index type "' .. itype .. '"')
  38.             local skip = -- detect if item should be skipped
  39.                 ((itype == 1) and ((i % 1) == 0) and (i >= 1) and (i <= length)) -- ipairs part
  40.                 or ((itype == 2) and (string.sub(i, 1, 1) == '_')) -- prefixed string
  41.             if not skip then
  42.                 r = r .. serialize(v, multiline, multiline and (depth + 1) or 0, i) .. ','
  43.                     .. (multiline and '\n' or ' ')
  44.             end
  45.         end
  46.         r = r .. (multiline and padding or '') .. '}'
  47.     elseif type(object) == 'string' then
  48.         r = r .. string.format('%q', object)
  49.     elseif type(object) == 'number' or type(object) == 'boolean' then
  50.         r = r .. tostring(object)
  51.     else
  52.         error('Unserializeable value "' .. tostring(object) .. '"')
  53.     end
  54.     return r
  55. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement