From 71d2d7d73f68146cad1324f304e990bf0d33db11 Mon Sep 17 00:00:00 2001 From: Jasmijn Wellner Date: Sun, 29 Dec 2024 19:33:44 +0100 Subject: [PATCH] Add an extension for #24 This is only a simplified system. A full implementation would need to add support for nested keys, and also support the same set of class libraries that bitser does. --- examples/bitser-templates.lua | 55 +++++++++++++++++++++++++++++++++++ examples/templates.lua | 38 ++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 examples/bitser-templates.lua create mode 100644 examples/templates.lua diff --git a/examples/bitser-templates.lua b/examples/bitser-templates.lua new file mode 100644 index 0000000..f9a77ac --- /dev/null +++ b/examples/bitser-templates.lua @@ -0,0 +1,55 @@ +-- this implements a simplified form of binser templates (without nested keys) + +local templates_by_identity = {} -- template -> name +local templates_by_name = {} +local class_by_templatename = {} + +local function bitser_match(value) + return value._template ~= nil and templates_by_identity[value._template] +end + +local function bitser_dump(value) + local templatename = templates_by_identity[value._template] + local template = templates_by_name[templatename] + local output = {templatename} + local extras = {} + for k, v in pairs(value) do + extras[k] = v + end + for i, key in ipairs(template) do + output[i + 1] = extras[key] + extras[key] = nil + end + output[#output + 1] = extras + return output +end + + +local function bitser_load(value) + local templatename = value[1] + local obj = {} + local template = templates_by_name[templatename] + for i, keyname in ipairs(template) do + obj[keyname] = value[i + 1] + end + for k, v in pairs(value[#value]) do + obj[k] = v + end + return setmetatable(obj, class_by_templatename[templatename]) +end + +local function register(class, name) + name = name or class.name + templates_by_identity[class._template] = name + templates_by_name[name] = class._template ---parse_template(class._template) + class_by_templatename[name] = class + return class +end + +return { + registerClass = register, + ["bitser-type"] = 'table', + ["bitser-match"] = bitser_match, + ["bitser-dump"] = bitser_dump, + ["bitser-load"] = bitser_load, +} diff --git a/examples/templates.lua b/examples/templates.lua new file mode 100644 index 0000000..56e5df1 --- /dev/null +++ b/examples/templates.lua @@ -0,0 +1,38 @@ +-- how to use the extension API to implement templates ala +-- https://github.com/bakpakin/binser#templates + +local bitser = require 'bitser' +local bitser_templates = require 'examples.bitser-templates' + +bitser.registerExtension('templates', bitser_templates) + +local template = { + "name", "age", "salary", "email", "nested" + --nested = {'more', 'nested', 'keys'} +} + +local Employee_MT = { + __name__ = 'Employee_MT', + name = "Employee", + _template = template +} +Employee_MT.__index = Employee_MT + +local joe = setmetatable({ + name = "Joe", + age = 11, + salary = "$1,000,000", + email = "joe@example.com", + nested = { + more = "blah", + nested = "FUBAR", + keys = "lost" + } +}, Employee_MT) + +bitser.registerClass(Employee_MT) +print('without templates:', #bitser.dumps(joe)) +bitser.unregisterClass('Employee_MT') + +bitser_templates.registerClass(Employee_MT) +print('with templates:', #bitser.dumps(joe))