feat(lua): Replace Autocall with Target-object, Autocall_config -> Autocall

Deep-copy `__namestack` decouples all instances of Autocall, previously it
worked as singleton. This allows to store call-chains as variables, aliases.

Target-object allows to avoid duplication of the target-parameter as required
with Autocall by storing them as variables.

Autocall_config renamed to Autocall for brevity.
This commit is contained in:
PRESFIL
2025-06-14 05:30:35 +00:00
committed by Jari Sundell
parent 20887b1ccb
commit c92becbb7c
+34 -23
View File
@@ -4,40 +4,51 @@ local args = {...}
local rtorrent = args[1]
-- Autocall
-- Allows syntax like `rtorrent.autocall.system.hostname()`
-- Passes an empty first argument implicitly, as "".
-- Allows syntax like:
-- - `rtorrent.autocall.system.hostname()` or
-- - `rtorrent.autocall.session.directory.set("/tmp/")`
-- Has assignment operator, syntax sugar for `.set()` with single argument
-- - `rtorrent.autocall.session.directory = "/tmp/"`
-- Autocall-chains can be reused as aliases:
-- ```lua
-- a = rtorrent.autocall.system
-- a.hostname() -- same as `rtorrent.autocall.system.hostname()`
-- a.pid() -- same as `rtorrent.autocall.system.pid()`
local mt = {}
function mt.__call (t, ...)
name = table.concat(rawget(t, "__namestack"), ".")
success, ret = pcall(rtorrent.call, name, ...)
tg = rawget(t, "__target") or ""
success, ret = pcall(rtorrent.call, name, tg, ...)
if not success then error(name..": "..ret, 2) end
return ret
end
function mt.__index (t, key)
ns = rawget(t, "__namestack") or {}
ns = {table.unpack(rawget(t, "__namestack") or {})}
tg = rawget(t, "__target") or nil
table.insert(ns, key)
return setmetatable({__namestack=ns}, mt)
end
rtorrent["autocall"] = setmetatable({}, mt)
-- Autocall-config
-- Same as autocall, but passes an empty first target implicitly, for syntax
-- like `rtorrent.autocall_config.session.directory.set("/tmp/")` or
-- like `rtorrent.autocall_config.session.directory = "/tmp/"`
local mt = {}
function mt.__call (t, ...)
name = table.concat(rawget(t, "__namestack"), ".")
success, ret = pcall(rtorrent.call, name, "", ...)
if not success then error(name..": "..ret, 2) end
return ret
end
function mt.__index (t, key)
ns = rawget(t, "__namestack") or {}
table.insert(ns, key)
return setmetatable({__namestack=ns}, mt)
return setmetatable({__namestack=ns, __target=tg}, mt)
end
function mt.__newindex (t, key, value)
t[key].set(value)
end
rtorrent["autocall_config"] = setmetatable({}, mt)
rtorrent["autocall"] = setmetatable({}, mt)
-- Target-object
-- Sets first argment for Autocall, for commands that require target.
-- Allows syntax like:
-- - `rtorrent.Target("some_infohash").d.name()` or
-- - `rtorrent.Target:new("some_infohash").d.name()`
-- Also can be stored as variable
local Target = setmetatable({
new = function (self, target)
return self(target)
end;
}, {
__call = function (self, target)
return setmetatable({__target=target}, mt)
end
})
rtorrent["Target"] = Target
return rtorrent