commit e24c536: [Minor] Update lua-tableshape to 2.6.0
Vsevolod Stakhov
vsevolod at rspamd.com
Sun Apr 9 11:49:03 UTC 2023
Author: Vsevolod Stakhov
Date: 2023-04-09 12:42:03 +0100
URL: https://github.com/rspamd/rspamd/commit/e24c536e5989e2b6d46cd8fb35667c860a175324 (HEAD -> master)
[Minor] Update lua-tableshape to 2.6.0
Issue: #4455
---
contrib/DEPENDENCY_INFO.md | 2 +-
contrib/lua-tableshape/tableshape.lua | 828 ++++++++++++++++++++++++++--------
2 files changed, 642 insertions(+), 188 deletions(-)
diff --git a/contrib/DEPENDENCY_INFO.md b/contrib/DEPENDENCY_INFO.md
index 49eca0992..745b60d76 100644
--- a/contrib/DEPENDENCY_INFO.md
+++ b/contrib/DEPENDENCY_INFO.md
@@ -17,7 +17,7 @@
| lua-lpeg | 1.0 | MIT | YES | rspamd text + alloc|
| lua-moses | ? | MIT | NO | |
| lua-lupa | ? | MIT | NO | |
-| lua-tableshape | ae67256 | MIT | NO | |
+| lua-tableshape | 2.6.0 | MIT | NO | |
| mumhash | ? | MIT | NO | |
| ngx-http-parser | 2.2.0 | MIT | YES | spamc support |
| Mozilla-PublicSuffix | ? | MIT | NO | |
diff --git a/contrib/lua-tableshape/tableshape.lua b/contrib/lua-tableshape/tableshape.lua
index 0f1f710f6..ccc735519 100644
--- a/contrib/lua-tableshape/tableshape.lua
+++ b/contrib/lua-tableshape/tableshape.lua
@@ -1,4 +1,5 @@
-local OptionalType, TaggedType, types
+local OptionalType, TaggedType, types, is_type
+local BaseType, TransformNode, SequenceNode, FirstOfNode, DescribeNode, NotType, Literal
local FailedTransform = { }
local unpack = unpack or table.unpack
local clone_state
@@ -22,11 +23,9 @@ clone_state = function(state_obj)
end
return out
end
-local BaseType, TransformNode, SequenceNode, FirstOfNode, DescribeNode
-local describe_literal
-describe_literal = function(val)
- local _exp_0 = type(val)
- if "string" == _exp_0 then
+local describe_type
+describe_type = function(val)
+ if type(val) == "string" then
if not val:match('"') then
return "\"" .. tostring(val) .. "\""
elseif not val:match("'") then
@@ -34,13 +33,23 @@ describe_literal = function(val)
else
return "`" .. tostring(val) .. "`"
end
+ elseif BaseType:is_base_type(val) then
+ return val:_describe()
else
- if BaseType:is_base_type(val) then
- return val:_describe()
- else
- return tostring(val)
+ return tostring(val)
+ end
+end
+local coerce_literal
+coerce_literal = function(value)
+ local _exp_0 = type(value)
+ if "string" == _exp_0 or "number" == _exp_0 or "boolean" == _exp_0 then
+ return Literal(value)
+ elseif "table" == _exp_0 then
+ if BaseType:is_base_type(value) then
+ return value
end
end
+ return nil, "failed to coerce literal into type, use types.literal() to test for literal value"
end
local join_names
join_names = function(items, sep, last_sep)
@@ -66,13 +75,6 @@ end
do
local _class_0
local _base_0 = {
- __eq = function(self, other)
- if BaseType:is_base_type(other) then
- return other(self)
- else
- return self(other[1])
- end
- end,
__div = function(self, fn)
return TransformNode(self, fn)
end,
@@ -83,20 +85,46 @@ do
return _with_0
end
end,
- __mul = function(self, right)
- return SequenceNode(self, right)
+ __mul = function(_left, _right)
+ local left, err = coerce_literal(_left)
+ if not (left) then
+ error("left hand side of multiplication: " .. tostring(_left) .. ": " .. tostring(err))
+ end
+ local right
+ right, err = coerce_literal(_right)
+ if not (right) then
+ error("right hand side of multiplication: " .. tostring(_right) .. ": " .. tostring(err))
+ end
+ return SequenceNode(left, right)
end,
- __add = function(self, right)
- if self.__class == FirstOfNode then
+ __add = function(_left, _right)
+ local left, err = coerce_literal(_left)
+ if not (left) then
+ error("left hand side of addition: " .. tostring(_left) .. ": " .. tostring(err))
+ end
+ local right
+ right, err = coerce_literal(_right)
+ if not (right) then
+ error("right hand side of addition: " .. tostring(_right) .. ": " .. tostring(err))
+ end
+ if left.__class == FirstOfNode then
local options = {
- unpack(self.options)
+ unpack(left.options)
}
table.insert(options, right)
return FirstOfNode(unpack(options))
+ elseif right.__class == FirstOfNode then
+ return FirstOfNode(left, unpack(right.options))
else
- return FirstOfNode(self, right)
+ return FirstOfNode(left, right)
end
end,
+ __unm = function(self, right)
+ return NotType(right)
+ end,
+ __tostring = function(self)
+ return self:_describe()
+ end,
_describe = function(self)
return error("Node missing _describe: " .. tostring(self.__class.__name))
end,
@@ -141,25 +169,8 @@ do
tag = name
})
end,
- clone_opts = function(self, merge)
- local opts
- if self.opts then
- do
- local _tbl_0 = { }
- for k, v in pairs(self.opts) do
- _tbl_0[k] = v
- end
- opts = _tbl_0
- end
- else
- opts = { }
- end
- if merge then
- for k, v in pairs(merge) do
- opts[k] = v
- end
- end
- return opts
+ clone_opts = function(self)
+ return error("clone_opts is not longer supported")
end,
__call = function(self, ...)
return self:check_value(...)
@@ -167,11 +178,7 @@ do
}
_base_0.__index = _base_0
_class_0 = setmetatable({
- __init = function(self)
- if self.opts then
- self._describe = self.opts.describe
- end
- end,
+ __init = function(self, opts) end,
__base = _base_0,
__name = "BaseType"
}, {
@@ -185,35 +192,24 @@ do
_base_0.__class = _class_0
local self = _class_0
self.is_base_type = function(self, val)
- if not (type(val) == "table") then
- return false
- end
- local cls = val and val.__class
- if not (cls) then
- return false
- end
- if BaseType == cls then
- return true
+ do
+ local mt = type(val) == "table" and getmetatable(val)
+ if mt then
+ if mt.__class then
+ return mt.__class.is_base_type == BaseType.is_base_type
+ end
+ end
end
- return self:is_base_type(cls.__parent)
+ return false
end
self.__inherited = function(self, cls)
cls.__base.__call = cls.__call
- cls.__base.__eq = self.__eq
cls.__base.__div = self.__div
cls.__base.__mod = self.__mod
cls.__base.__mul = self.__mul
cls.__base.__add = self.__add
- local mt = getmetatable(cls)
- local create = mt.__call
- mt.__call = function(cls, ...)
- local ret = create(cls, ...)
- if ret.opts and ret.opts.optional then
- return ret:is_optional()
- else
- return ret
- end
- end
+ cls.__base.__unm = self.__unm
+ cls.__base.__tostring = self.__tostring
end
BaseType = _class_0
end
@@ -274,8 +270,6 @@ do
end
})
_base_0.__class = _class_0
- local self = _class_0
- self.transformer = true
if _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
@@ -293,11 +287,7 @@ do
local _list_0 = self.sequence
for _index_0 = 1, #_list_0 do
local i = _list_0[_index_0]
- if type(i) == "table" and i._describe then
- _accum_0[_len_0] = i:_describe()
- else
- _accum_0[_len_0] = describe_literal(i)
- end
+ _accum_0[_len_0] = describe_type(i)
_len_0 = _len_0 + 1
end
item_names = _accum_0
@@ -346,8 +336,6 @@ do
end
})
_base_0.__class = _class_0
- local self = _class_0
- self.transformer = true
if _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
@@ -365,11 +353,7 @@ do
local _list_0 = self.options
for _index_0 = 1, #_list_0 do
local i = _list_0[_index_0]
- if type(i) == "table" and i._describe then
- _accum_0[_len_0] = i:_describe()
- else
- _accum_0[_len_0] = describe_literal(i)
- end
+ _accum_0[_len_0] = describe_type(i)
_len_0 = _len_0 + 1
end
item_names = _accum_0
@@ -421,8 +405,6 @@ do
end
})
_base_0.__class = _class_0
- local self = _class_0
- self.transformer = true
if _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
@@ -502,6 +484,66 @@ do
end
DescribeNode = _class_0
end
+local AnnotateNode
+do
+ local _class_0
+ local _parent_0 = BaseType
+ local _base_0 = {
+ format_error = function(self, value, err)
+ return tostring(tostring(value)) .. ": " .. tostring(err)
+ end,
+ _transform = function(self, value, state)
+ local new_value, state_or_err = self.base_type:_transform(value, state)
+ if new_value == FailedTransform then
+ return FailedTransform, self:format_error(value, state_or_err)
+ else
+ return new_value, state_or_err
+ end
+ end,
+ _describe = function(self)
+ if self.base_type._describe then
+ return self.base_type:_describe()
+ end
+ end
+ }
+ _base_0.__index = _base_0
+ setmetatable(_base_0, _parent_0.__base)
+ _class_0 = setmetatable({
+ __init = function(self, base_type, opts)
+ self.base_type = assert(coerce_literal(base_type))
+ if opts then
+ if opts.format_error then
+ self.format_error = assert(types.func:transform(opts.format_error))
+ end
+ end
+ end,
+ __base = _base_0,
+ __name = "AnnotateNode",
+ __parent = _parent_0
+ }, {
+ __index = function(cls, name)
+ local val = rawget(_base_0, name)
+ if val == nil then
+ local parent = rawget(cls, "__parent")
+ if parent then
+ return parent[name]
+ end
+ else
+ return val
+ end
+ end,
+ __call = function(cls, ...)
+ local _self_0 = setmetatable({}, _base_0)
+ cls.__init(_self_0, ...)
+ return _self_0
+ end
+ })
+ _base_0.__class = _class_0
+ if _parent_0.__inherited then
+ _parent_0.__inherited(_parent_0, _class_0)
+ end
+ AnnotateNode = _class_0
+end
do
local _class_0
local _parent_0 = BaseType
@@ -549,13 +591,16 @@ do
end,
_describe = function(self)
local base_description = self.base_type:_describe()
- return tostring(base_description) .. " tagged " .. tostring(describe_literal(self.tag))
+ return tostring(base_description) .. " tagged " .. tostring(describe_type(self.tag_name))
end
}
_base_0.__index = _base_0
setmetatable(_base_0, _parent_0.__base)
_class_0 = setmetatable({
__init = function(self, base_type, opts)
+ if opts == nil then
+ opts = { }
+ end
self.base_type = base_type
self.tag_name = assert(opts.tag, "tagged type missing tag")
self.tag_type = type(self.tag_name)
@@ -673,10 +718,9 @@ do
_base_0.__index = _base_0
setmetatable(_base_0, _parent_0.__base)
_class_0 = setmetatable({
- __init = function(self, base_type, opts)
- self.base_type, self.opts = base_type, opts
- _class_0.__parent.__init(self)
- return assert(BaseType:is_base_type(base_type), "expected a type checker")
+ __init = function(self, base_type)
+ self.base_type = base_type
+ return assert(BaseType:is_base_type(self.base_type), "expected a type checker")
end,
__base = _base_0,
__name = "OptionalType",
@@ -761,7 +805,7 @@ do
_transform = function(self, value, state)
local got = type(value)
if self.t ~= got then
- return FailedTransform, "expected type " .. tostring(describe_literal(self.t)) .. ", got " .. tostring(describe_literal(got))
+ return FailedTransform, "expected type " .. tostring(describe_type(self.t)) .. ", got " .. tostring(describe_type(got))
end
if self.length_type then
local len = #value
@@ -780,12 +824,12 @@ do
else
l = types.range(left, right)
end
- return Type(self.t, self:clone_opts({
+ return Type(self.t, {
length = l
- }))
+ })
end,
_describe = function(self)
- local t = "type " .. tostring(describe_literal(self.t))
+ local t = "type " .. tostring(describe_type(self.t))
if self.length_type then
t = t .. " length_type " .. tostring(self.length_type:_describe())
end
@@ -796,11 +840,12 @@ do
setmetatable(_base_0, _parent_0.__base)
_class_0 = setmetatable({
__init = function(self, t, opts)
- self.t, self.opts = t, opts
- if self.opts then
- self.length_type = self.opts.length
+ self.t = t
+ if opts then
+ if opts.length then
+ self.length_type = assert(coerce_literal(opts.length))
+ end
end
- return _class_0.__parent.__init(self)
end,
__base = _base_0,
__name = "Type",
@@ -847,7 +892,7 @@ do
return FailedTransform, "non number field: " .. tostring(i)
end
if not (i == k) then
- return FailedTransform, "non array index, got " .. tostring(describe_literal(i)) .. " but expected " .. tostring(describe_literal(k))
+ return FailedTransform, "non array index, got " .. tostring(describe_type(i)) .. " but expected " .. tostring(describe_type(k))
end
k = k + 1
end
@@ -857,9 +902,8 @@ do
_base_0.__index = _base_0
setmetatable(_base_0, _parent_0.__base)
_class_0 = setmetatable({
- __init = function(self, opts)
- self.opts = opts
- return _class_0.__parent.__init(self)
+ __init = function(self, ...)
+ return _class_0.__parent.__init(self, ...)
end,
__base = _base_0,
__name = "ArrayType",
@@ -904,7 +948,7 @@ do
if type(i) == "table" and i._describe then
_accum_0[_len_0] = i:_describe()
else
- _accum_0[_len_0] = describe_literal(i)
+ _accum_0[_len_0] = describe_type(i)
end
_len_0 = _len_0 + 1
end
@@ -947,9 +991,8 @@ do
_base_0.__index = _base_0
setmetatable(_base_0, _parent_0.__base)
_class_0 = setmetatable({
- __init = function(self, options, opts)
- self.options, self.opts = options, opts
- _class_0.__parent.__init(self)
+ __init = function(self, options)
+ self.options = options
assert(type(self.options) == "table", "expected table for options in one_of")
local fast_opts = types.array_of(types.number + types.string)
if fast_opts(self.options) then
@@ -1004,11 +1047,7 @@ do
local _list_0 = self.types
for _index_0 = 1, #_list_0 do
local i = _list_0[_index_0]
- if type(i) == "table" and i._describe then
- _accum_0[_len_0] = i:_describe()
- else
- _accum_0[_len_0] = describe_literal(i)
- end
+ _accum_0[_len_0] = describe_type(i)
_len_0 = _len_0 + 1
end
item_names = _accum_0
@@ -1030,9 +1069,8 @@ do
_base_0.__index = _base_0
setmetatable(_base_0, _parent_0.__base)
_class_0 = setmetatable({
- __init = function(self, types, opts)
- self.types, self.opts = types, opts
- _class_0.__parent.__init(self)
+ __init = function(self, types)
+ self.types = types
assert(type(self.types) == "table", "expected table for first argument")
local _list_0 = self.types
for _index_0 = 1, #_list_0 do
@@ -1073,7 +1111,7 @@ do
local _parent_0 = BaseType
local _base_0 = {
_describe = function(self)
- return "array of " .. tostring(describe_literal(self.expected))
+ return "array of " .. tostring(describe_type(self.expected))
end,
_transform = function(self, value, state)
local pass, err = types.table(value)
@@ -1095,7 +1133,7 @@ do
local transformed_item
if is_literal then
if self.expected ~= item then
- return FailedTransform, "array item " .. tostring(idx) .. ": expected " .. tostring(describe_literal(self.expected))
+ return FailedTransform, "array item " .. tostring(idx) .. ": expected " .. tostring(describe_type(self.expected))
else
transformed_item = item
end
@@ -1139,12 +1177,13 @@ do
setmetatable(_base_0, _parent_0.__base)
_class_0 = setmetatable({
__init = function(self, expected, opts)
- self.expected, self.opts = expected, opts
- if self.opts then
- self.keep_nils = self.opts.keep_nils
- self.length_type = self.opts.length
+ self.expected = expected
+ if opts then
+ self.keep_nils = opts.keep_nils and true
+ if opts.length then
+ self.length_type = assert(coerce_literal(opts.length))
+ end
end
- return _class_0.__parent.__init(self)
end,
__base = _base_0,
__name = "ArrayOf",
@@ -1175,11 +1214,130 @@ do
end
ArrayOf = _class_0
end
+local ArrayContains
+do
+ local _class_0
+ local _parent_0 = BaseType
+ local _base_0 = {
+ short_circuit = true,
+ keep_nils = false,
+ _describe = function(self)
+ return "array containing " .. tostring(describe_type(self.contains))
+ end,
+ _transform = function(self, value, state)
+ local pass, err = types.table(value)
+ if not (pass) then
+ return FailedTransform, err
+ end
+ local is_literal = not BaseType:is_base_type(self.contains)
+ local contains = false
+ local copy, k
+ for idx, item in ipairs(value) do
+ local skip_item = false
+ local transformed_item
+ if is_literal then
+ if self.contains == item then
+ contains = true
+ end
+ transformed_item = item
+ else
+ local item_val, new_state = self.contains:_transform(item, state)
+ if item_val == FailedTransform then
+ transformed_item = item
+ else
+ state = new_state
+ contains = true
+ if item_val == nil and not self.keep_nils then
+ skip_item = true
+ else
+ transformed_item = item_val
+ end
+ end
+ end
+ if transformed_item ~= item or skip_item then
+ if not (copy) then
+ do
+ local _accum_0 = { }
+ local _len_0 = 1
+ local _max_0 = idx - 1
+ for _index_0 = 1, _max_0 < 0 and #value + _max_0 or _max_0 do
+ local i = value[_index_0]
+ _accum_0[_len_0] = i
+ _len_0 = _len_0 + 1
+ end
+ copy = _accum_0
+ end
+ k = idx
+ end
+ end
+ if copy and not skip_item then
+ copy[k] = transformed_item
+ k = k + 1
+ end
+ if contains and self.short_circuit then
+ if copy then
+ for kdx = idx + 1, #value do
+ copy[k] = value[kdx]
+ k = k + 1
+ end
+ end
+ break
+ end
+ end
+ if not (contains) then
+ return FailedTransform, "expected " .. tostring(self:_describe())
+ end
+ return copy or value, state
+ end
+ }
+ _base_0.__index = _base_0
+ setmetatable(_base_0, _parent_0.__base)
+ _class_0 = setmetatable({
+ __init = function(self, contains, opts)
+ self.contains = contains
+ assert(self.contains, "missing contains")
+ if opts then
+ self.short_circuit = opts.short_circuit and true
+ self.keep_nils = opts.keep_nils and true
+ end
+ end,
+ __base = _base_0,
+ __name = "ArrayContains",
+ __parent = _parent_0
+ }, {
+ __index = function(cls, name)
+ local val = rawget(_base_0, name)
+ if val == nil then
+ local parent = rawget(cls, "__parent")
+ if parent then
+ return parent[name]
+ end
+ else
+ return val
+ end
+ end,
+ __call = function(cls, ...)
+ local _self_0 = setmetatable({}, _base_0)
+ cls.__init(_self_0, ...)
+ return _self_0
+ end
+ })
+ _base_0.__class = _class_0
+ local self = _class_0
+ self.type_err_message = "expecting table"
+ if _parent_0.__inherited then
+ _parent_0.__inherited(_parent_0, _class_0)
+ end
+ ArrayContains = _class_0
+end
local MapOf
do
local _class_0
local _parent_0 = BaseType
local _base_0 = {
+ _describe = function(self)
+ return "map of " .. tostring(self.expected_key:_describe()) .. " -> " .. tostring(self.expected_value:_describe())
+ end,
_transform = function(self, value, state)
local pass, err = types.table(value)
if not (pass) then
@@ -1196,7 +1354,7 @@ do
local new_v = v
if key_literal then
if k ~= self.expected_key then
- return FailedTransform, "map key expected " .. tostring(describe_literal(self.expected_key))
+ return FailedTransform, "map key expected " .. tostring(describe_type(self.expected_key))
end
else
new_k, state = self.expected_key:_transform(k, state)
@@ -1206,7 +1364,7 @@ do
end
if value_literal then
if v ~= self.expected_value then
- return FailedTransform, "map value expected " .. tostring(describe_literal(self.expected_value))
+ return FailedTransform, "map value expected " .. tostring(describe_type(self.expected_value))
end
else
new_v, state = self.expected_value:_transform(v, state)
@@ -1234,9 +1392,9 @@ do
_base_0.__index = _base_0
setmetatable(_base_0, _parent_0.__base)
_class_0 = setmetatable({
- __init = function(self, expected_key, expected_value, opts)
- self.expected_key, self.expected_value, self.opts = expected_key, expected_value, opts
- return _class_0.__parent.__init(self)
+ __init = function(self, expected_key, expected_value)
+ self.expected_key = coerce_literal(expected_key)
+ self.expected_value = coerce_literal(expected_value)
end,
__base = _base_0,
__name = "MapOf",
@@ -1270,10 +1428,13 @@ do
local _class_0
local _parent_0 = BaseType
local _base_0 = {
+ open = false,
+ check_all = false,
is_open = function(self)
*** OUTPUT TRUNCATED, 590 LINES SKIPPED ***
More information about the Commits
mailing list