local M = {}
local ACTION_TAG = {}
local ACTION_SPACE_TAG = {}
function M.build_action(name)
if type(name) ~= "string" then
error(string.format("sw.action: name must be string, got %s", type(name)), 2)
end
return function(spec)
if type(spec) ~= "table" then
error(string.format("sw.action '%s': spec must be a table", name), 2)
end
if spec.description == nil then
error(string.format("sw.action '%s': description is required", name), 2)
end
if type(spec.description) ~= "string" then
error(string.format("sw.action '%s': description must be string, got %s", name, type(spec.description)), 2)
end
local context = {}
for k, v in pairs(spec) do
if k ~= "description" then
context[k] = v
end
end
return {
_tag = ACTION_TAG,
name = name,
description = spec.description,
context = context,
}
end
end
function M.is_action(v)
return type(v) == "table" and v._tag == ACTION_TAG
end
function M.build_action_space(list)
if type(list) ~= "table" or #list < 1 then
error("sw.actions: at least 1 action required", 2)
end
local actions = {}
local by_name = {}
for i, entry in ipairs(list) do
if not M.is_action(entry) then
error(string.format("sw.actions[%d]: must be an action (use sw.action)", i), 2)
end
if by_name[entry.name] then
error(string.format("sw.actions: duplicate action name '%s'", entry.name), 2)
end
actions[#actions + 1] = entry
by_name[entry.name] = entry
end
return {
_tag = ACTION_SPACE_TAG,
actions = actions,
by_name = by_name,
}
end
function M.is_action_space(v)
return type(v) == "table" and v._tag == ACTION_SPACE_TAG
end
return M