tableshape
tableshape copied to clipboard
nested `extra_fields` in combination with `shape`
this is like a really weird issue and i am sorry for even opening it but i kinda have a question. I somewhat know lua/luajit because i am a maintainer of a somewhat popular project, so a coworker asked me if i could look into a lua bug that he had with another open source software, rspamd.
That software uses tableshape, so i looked into that rspamd bug (https://github.com/rspamd/rspamd/issues/4318#issuecomment-1453502529) and after that into tableshape documentation + source code and i think i found a missuse of tableshape in rspamd. I know that is not your issue but i kinda wanna make sure that its actually a missuse.
So i've created a minimal reproduce of the code that is being executed in rspamd.
package.path = package.path .. ";./?.lua;"
local ts = require("contrib.lua-tableshape.tableshape").types
local lua_redis_common = ts.shape {
password = ts.string:is_optional(),
}
local lua_redis =
-- Allow separate read/write servers to allow usage in the `extra_fields`
ts.shape({
read_servers = ts.string + ts.array_of(ts.string),
}, { extra_fields = lua_redis_common }) + ts.shape({
write_servers = ts.string + ts.array_of(ts.string),
}, { extra_fields = lua_redis_common }) + ts.shape({
read_servers = ts.string + ts.array_of(ts.string),
write_servers = ts.string + ts.array_of(ts.string),
}, { extra_fields = lua_redis_common })
local settings_schema = ts.shape({
key_prefix = ts.string,
nrows = ts.number,
compress = ts.boolean,
}, { extra_fields = lua_redis })
local obj1 = {
key_prefix = "rs_history",
nrows = 1000,
compress = true,
read_servers = "127.0.0.1:6381",
write_servers = "127.0.0.1:6381",
-- password = "<password hidden>",
}
local res, err = settings_schema:transform(obj1)
print(res, err)
as soon as i comment in password everything "explodes" with the following error
nil field "password": expected { "read_servers" = type "string", or array of type "string" }, { "write_servers" = type "string", or array of type "string" }, { "write_servers" = type "string", or array of type "string", "read_servers
" = type "string", or array of type "string" }, { "servers" = type "string", or array of type "string" }, or { "server" = type "string", or array of type "string" }
But it should be possible to optionally add password to that table.
If you confirm that this is a usecase that is currently not supported and never will be i could just rewrite the code in rspamd :laughing: