Skip to content

Instantly share code, notes, and snippets.

@catwell
Last active October 30, 2015 10:10
Show Gist options
  • Save catwell/675c145b470e168834bb to your computer and use it in GitHub Desktop.
Save catwell/675c145b470e168834bb to your computer and use it in GitHub Desktop.
mp_magic
-- For use with https://github.com/fperrad/lua-MessagePack
-- Usage:
-- local mp = require "MessagePack"
-- local MP = mp_magic(mp)
-- mp.pack{ this_is_a_string = MP{binary = "this_is_a_binary"} }
local mp_magic = function(mp)
if mp.mpmagic then return mp.mpmagic end
local mp_mt = {}
local new = function(t) return setmetatable(t, mp_mt) end
local orig = mp.packers.table
local packers = setmetatable({
map = function(buf, v)
local n = 0
for _ in pairs(v) do n = n + 1 end
return mp.packers.map(buf, v, n)
end,
array = function(buf, v)
return mp.packers.array(buf, v, #v)
end,
}, { __index = mp.packers })
local _packer = function(buf, t)
if getmetatable(t) == mp_mt then
local k, v = next(t)
if k and type(k) == "string" and packers[k] then
return packers[k](buf, v)
end
end
return orig(buf, t)
end
mp.packers.table = _packer
mp.mpmagic = new
return new
end
-- For use with https://github.com/fperrad/lua-MessagePack
-- Usage:
-- local mp = require "MessagePack"
-- local MP = mp_magic(mp)
-- mp.pack {
-- a_binary = MP.binary(""),
-- a_string = MP.string(""),
-- a_map = MP.map({}),
-- an_array = MP.array({}),
-- a_float = MP.float(42),
-- }
local mp_magic = function(mp)
if mp.mpmagic then return mp.mpmagic end
local unknown = function(t, k)
t[k] = { packer = mp.packers[k] }
return t[k]
end
mts = setmetatable({
map = {
packer = function(buf, v)
local n = 0
for _ in pairs(v) do n = n + 1 end
return mp.packers.map(buf, v, n)
end
},
array = {
packer = function(buf, v)
return mp.packers.array(buf, v, #v)
end
},
}, {
__index = function(t, k)
t[k] = { packer = mp.packers[k] }
return t[k]
end
})
mp.mpmagic = setmetatable({}, {
__index = function(t, k)
local mt = mts[k]
if mt then return function(v)
return setmetatable({v}, mt)
end end
end
})
local orig = mp.packers.table
mp.packers.table = function(buf, t)
local mt = getmetatable(t)
if mt and mt.packer and type(mt.packer) == "function" then
return mt.packer(buf, t[1])
end
return orig(buf, t)
end
return mp.mpmagic
end
@catwell
Copy link
Author

catwell commented Oct 30, 2015

Simpler and often enough, from fperrad:

local mp = require 'MessagePack'
mp.packers['function'] = function (buffer, fct)
    fct(buffer)
end

local function BINARY (str)
    return function (buffer)
        mp.packers['binary'](buffer, str)
    end
end

local function FLOAT (n)
    return function (buffer)
        mp.packers['float'](buffer, n)
    end
end

mp.pack { 'encoded_with_global_settings', BINARY'encoded_as_binary', 42, FLOAT(42) }

The way I use this:

do -- binary packer
    if not rawget(mp.packers, "function") then
        rawset(mp.packers, "function", function(buf, f) f(buf) end)
    end
    mp.BIN = function(s)
        return function(buf) mp.packers["binary"](buf, s) end
    end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment