From: Vsevolod Stakhov Date: Tue, 18 Nov 2025 12:03:34 +0000 (+0000) Subject: [Minor] Migrate lualib/plugins/ratelimit.lua to lua_shape X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bdb6f5546ac808c5bf828bc113e38fbdb207bd67;p=thirdparty%2Frspamd.git [Minor] Migrate lualib/plugins/ratelimit.lua to lua_shape Replace tableshape with lua_shape in ratelimit utilities. Changes: - ts.shape { ... } → T.table({ ... }) - ts.number + ts.string / fn → T.one_of({T.number(), T.transform(T.string(), fn)}) - :is_optional() → :optional() - Added comprehensive documentation to all fields Schema: bucket_schema for ratelimit bucket with burst/rate limits, optional symbol, message, and skip flags. --- diff --git a/lualib/plugins/ratelimit.lua b/lualib/plugins/ratelimit.lua index 24afed1f8e..0b674f9c1e 100644 --- a/lualib/plugins/ratelimit.lua +++ b/lualib/plugins/ratelimit.lua @@ -16,7 +16,7 @@ limitations under the License. local rspamd_logger = require "rspamd_logger" local lua_util = require "lua_util" -local ts = require("tableshape").types +local T = require "lua_shape.core" local exports = {} @@ -97,14 +97,20 @@ local function str_to_rate(str) return divisor / divider end -local bucket_schema = ts.shape { - burst = ts.number + ts.string / lua_util.dehumanize_number, - rate = ts.number + ts.string / str_to_rate, - skip_recipients = ts.boolean:is_optional(), - symbol = ts.string:is_optional(), - message = ts.string:is_optional(), - skip_soft_reject = ts.boolean:is_optional(), -} +local bucket_schema = T.table({ + burst = T.one_of({ + T.number(), + T.transform(T.string(), lua_util.dehumanize_number) + }):doc({ summary = "Burst size (number of messages)" }), + rate = T.one_of({ + T.number(), + T.transform(T.string(), str_to_rate) + }):doc({ summary = "Rate limit (messages per time unit)" }), + skip_recipients = T.boolean():optional():doc({ summary = "Skip per-recipient limits" }), + symbol = T.string():optional():doc({ summary = "Custom symbol name" }), + message = T.string():optional():doc({ summary = "Custom reject message" }), + skip_soft_reject = T.boolean():optional():doc({ summary = "Skip soft reject" }), +}):doc({ summary = "Ratelimit bucket configuration" }) exports.parse_limit = function(name, data) if type(data) == 'table' then