This is a general trait pattern used to imitate variadic arguments. For example for ToLuaMulti in mlua - Rust
impl<'lua, T: ToLua<'lua>> ToLuaMulti<'lua> for T // some base types
impl<'lua> ToLuaMulti<'lua> for () // no argument
impl<'lua, A> ToLuaMulti<'lua> for (A,) where A: ToLuaMulti<'lua>, // one argument
impl<'lua, B, A> ToLuaMulti<'lua> for (B, A) // two arguments
where
B: ToLua<'lua>,
A: ToLuaMulti<'lua>,
... // more arguments as many as you want to define
then for the callbacks, the trait bounds can be
pub fn call<A: ToLuaMulti<'lua>, R: FromLuaMulti<'lua>>(
&self,
args: A
) -> Result<R>
// you can use it as follows
let sum: Function = lua.load(
r#"
function(a, b)
return a + b
end
"#).eval()?;
assert_eq!(sum.call::<_, u32>((3, 4))?, 3 + 4); // two arguments: `_` is `(i32, i32)`
let sum: Function = lua.load(
r#"
function()
return 1
end
"#).eval()?;
assert_eq!(sum.call::<_, u32>(())?, 1); // no argument: `_` is `()`
or similar to the closure style in OP
pub fn create_function<'lua, A, R, F>(
&'lua self,
func: F
) -> Result<Function<'lua>>
where
A: FromLuaMulti<'lua>,
R: ToLuaMulti<'lua>,
F: 'static + MaybeSend + Fn(&'lua Lua, A) -> Result<R>,
// you can use it as follows
let nop = lua.create_function(|_, _: ()| { // no argument
Ok(())
});
// equivalent to `function() end` in lua
let greet = lua.create_function(|_, name: String| { // one argument
println!("Hello, {}!", name);
Ok(())
});
// equivalent to `function(name) print("Hello, ", name, "!") end` in lua