Added serialization of metatables using __tostring (when present).

This commit is contained in:
Paul Kulchenko 2012-11-16 21:21:42 -08:00
parent d8e92a3388
commit 07e85484df
3 changed files with 18 additions and 3 deletions

View File

@ -128,6 +128,10 @@ See LICENSE file.
## History ## History
Nov 16 2012 v0.19
- Fixed an issue with serializing shared functions as keys.
- Added serialization of metatables using __tostring (when present).
Sep 13 2012 v0.18 Sep 13 2012 v0.18
- Fixed an issue with serializing data structures with circular references that require emitting temporary variables. - Fixed an issue with serializing data structures with circular references that require emitting temporary variables.
- Fixed an issue with serializing keys pointing to shared references. - Fixed an issue with serializing keys pointing to shared references.

View File

@ -1,4 +1,4 @@
local n, v = "serpent", 0.18 -- (C) 2012 Paul Kulchenko; MIT License local n, v = "serpent", 0.19 -- (C) 2012 Paul Kulchenko; MIT License
local c, d = "Paul Kulchenko", "Serializer and pretty printer of Lua data types" local c, d = "Paul Kulchenko", "Serializer and pretty printer of Lua data types"
local snum = {[tostring(1/0)]='1/0 --[[math.huge]]',[tostring(-1/0)]='-1/0 --[[-math.huge]]',[tostring(0/0)]='0/0'} local snum = {[tostring(1/0)]='1/0 --[[math.huge]]',[tostring(-1/0)]='-1/0 --[[-math.huge]]',[tostring(0/0)]='0/0'}
local badtype = {thread = true, userdata = true} local badtype = {thread = true, userdata = true}
@ -57,6 +57,8 @@ local function s(t, opts)
elseif ttype == "table" then elseif ttype == "table" then
if level >= maxl then return tag..'{}'..comment('max', level) end if level >= maxl then return tag..'{}'..comment('max', level) end
seen[t] = insref or spath -- set path to use as reference seen[t] = insref or spath -- set path to use as reference
if getmetatable(t) and getmetatable(t).__tostring
then return tag..safestr(tostring(t))..comment("meta",l) end
if next(t) == nil then return tag..'{}'..comment(t, level) end -- table empty if next(t) == nil then return tag..'{}'..comment(t, level) end -- table empty
local maxn, o, out = #t, {}, {} local maxn, o, out = #t, {}, {}
for key = 1, maxn do table.insert(o, key) end for key = 1, maxn do table.insert(o, key) end

View File

@ -96,7 +96,6 @@ do
local tbl = {'tbl'} local tbl = {'tbl'}
a[3] = {[{}] = {happy = tbl}, sad = tbl} a[3] = {[{}] = {happy = tbl}, sad = tbl}
print(serpent.dump(a, {sparse = false, nocode = true}))
assert(loadstring(serpent.dump(a, {sparse = false, nocode = true})), assert(loadstring(serpent.dump(a, {sparse = false, nocode = true})),
"table as key with circular/shared reference: failed") "table as key with circular/shared reference: failed")
end end
@ -108,9 +107,19 @@ do
a.a[function1]=function() end a.a[function1]=function() end
a.b=a.a[function1] a.b=a.a[function1]
print(serpent.dump(a, {sparse = false, nocode = true}))
assert(loadstring(serpent.dump(a, {sparse = false, nocode = true})), assert(loadstring(serpent.dump(a, {sparse = false, nocode = true})),
"functions as shared references while processing shared refs: failed") "functions as shared references while processing shared refs: failed")
end end
-- test serialization of metatable with __tostring
do
local mt = {}
mt.__tostring = function(t) return 'table with ' .. #t .. ' entries' end
local a = {'a', 'b'}
setmetatable(a, mt)
assert(loadstring(serpent.dump(a, {sparse = false, nocode = true, comment = true})),
"metatable with __tostring serialized with a comment: failed")
end
print("All tests passed.") print("All tests passed.")