A 'debug' mode where type metadata is added even in the binary case
nikki93 opened this issue · comments
Could be useful to enable a global 'debug' mode where methods like :string
and :number
etc. add type metadata in the serialized form, so that the deserializer would error if there is a mismatch. Could even go the extra mile and add hint keys that it'd check for a match (eg. :number(100, 'health')
) but ignore in non-debug mode.
I'm mostly using this in a multiplayer game scenario and if there are bugs where the receiver isn't gleaning the format properly from the message this would help. I'm just thinking ahead though and haven't hit concrete cases of this yet.
Here's a quick and easy way to add type information to every value written, and check the type when reading:
DEBUG = true -- the global debug flag
local function writeChecked(self, value, type)
if DEBUG then
self:string(type)
end
return self[type](self, value)
end
local function readChecked(self, type)
if DEBUG then
assert(type == self:string(), "Mismatching types in data")
end
return self[type](self)
end
Usage:
local w = BlobWriter()
writeChecked(w, "hello", "string")
writeChecked(w, "world", "string")
local r = BlobReader(w:tostring())
local hello = readChecked(r, "string") -- okay
local world = readChecked(r, "u32") -- error: type mismatch
This works for all supported data types, not just Lua types. Note that the overhead for type information can be significant with this approach, but it also has a low probability for giving false positives. Shorter type identifiers with low overhead, for example single byte values, could lead to situations where user data is mistaken for type information, making it even harder to find mistakes in your code.
Doing this correctly and in an efficient way is not trivial. Introducing some kind of schema definition might be the way to go here.