local pipe = sel.processor_pipe or E
local first_elt = pipe[1]
- if first_elt and first_elt.method then
+ if first_elt and (first_elt.method or
+ fun.any(function(t) return t == 'userdata' or t == 'table' end, first_elt.types)) then
-- Explicit conversion
local meth = first_elt
-- Map method to a list of inputs, excluding empty elements
input = fun.filter(function(map_elt) return map_elt end,
fun.map(function(list_elt)
- local ret, _ = meth.process(list_elt, pt)
+ local ret, _ = meth.process(list_elt, pt, meth.args)
return ret
end, input))
etype = 'string_list'
pipe = fun.drop_n(1, pipe)
elseif etype:match('^userdata') or etype:match('^table') then
-- Implicit conversion
-
local pt = pure_type(etype)
if not pt then
end, input))
etype = 'string_list'
end
+ else
+ lua_util.debugm(M, task, 'avoid implicit conversion as the transformer accepts complex input')
end
-- Now we fold elements using left fold
if not res or not res[1] then return nil end -- Pipeline failed
if not allowed_type(res[2]) then
-
-- Search for implicit conversion
local pt = pure_type(res[2])
if pt then
+
lua_util.debugm(M, task, 'apply implicit map %s->string_list', pt)
res[1] = fun.map(function(e) return implicit_tostring(pt, e) end, res[1])
res[2] = 'string_list'
local processor = lua_util.shallowcopy(transform_function[proc_name])
processor.name = proc_name
processor.args = proc_tbl[2] or E
+ logger.errx('hui: %s -> %s', proc_name, processor.args)
if not check_args(processor.name, processor.args_schema, processor.args) then
pipeline_error = 'args schema for ' .. proc_name
['description'] = 'Joins strings into a single string using separator in the argument',
['args_schema'] = {ts.string:is_optional()}
},
+ -- Joins strings into a set of strings using N elements and a separator in the argument
+ ['join_nth'] = {
+ ['types'] = {
+ ['string_list'] = true
+ },
+ ['process'] = function(inp, _, args)
+ local step = args[1]
+ local sep = args[2] or ''
+ local inp_t = fun.totable(inp)
+ local res = {}
+
+ for i=1, #inp_t, step do
+ table.insert(res, table.concat(inp_t, sep, i, i + step))
+ end
+ return res,'string_list'
+ end,
+ ['description'] = 'Joins strings into a set of strings using N elements and a separator in the argument',
+ ['args_schema'] = {ts.number + ts.string / tonumber, ts.string:is_optional()}
+ },
+ -- Joins tables into a table of strings
+ ['join_tables'] = {
+ ['types'] = {
+ ['string_list'] = true
+ },
+ ['process'] = function(inp, _, args)
+ local sep = args[1] or ''
+ return fun.map(function(t) return table.concat(t, sep) end, inp), 'string_list'
+ end,
+ ['description'] = 'Joins tables into a table of strings',
+ ['args_schema'] = {ts.string:is_optional()}
+ },
-- Sort strings
['sort'] = {
['types'] = {
['description'] = 'Removes all nils from a list of strings (when converted implicitly)',
['args_schema'] = {}
},
+ -- Call a set of methods on a userdata object
+ ['apply_methods'] = {
+ ['types'] = {
+ ['userdata'] = true,
+ },
+ ['process'] = function(inp, _, args)
+ local res = {}
+ for _,arg in ipairs(args) do
+ local meth = inp[arg]
+ local ret = meth(inp)
+ if not ret then return nil end
+ table.insert(res, tostring(ret))
+ end
+ return res,'string_list'
+ end,
+ ['description'] = 'Apply a list of method calls to the userdata object',
+ }
}
transform_function.match = transform_function.regexp