Add `call()` function to `TableExt` to call tables with `__call` metamethod as functions
This commit is contained in:
parent
55c8af1e6b
commit
170818c469
37
src/table.rs
37
src/table.rs
|
@ -502,6 +502,24 @@ impl<'lua> AsRef<Table<'lua>> for Table<'lua> {
|
|||
|
||||
/// An extension trait for `Table`s that provides a variety of convenient functionality.
|
||||
pub trait TableExt<'lua> {
|
||||
/// Calls the table as function assuming it has `__call` metamethod.
|
||||
///
|
||||
/// The metamethod is called with the table as its first argument, followed by the passed arguments.
|
||||
fn call<A, R>(&self, args: A) -> Result<R>
|
||||
where
|
||||
A: ToLuaMulti<'lua>,
|
||||
R: FromLuaMulti<'lua>;
|
||||
|
||||
/// Asynchronously calls the table as function assuming it has `__call` metamethod.
|
||||
///
|
||||
/// The metamethod is called with the table as its first argument, followed by the passed arguments.
|
||||
#[cfg(feature = "async")]
|
||||
fn call_async<'fut, A, R>(&self, args: A) -> LocalBoxFuture<'fut, Result<R>>
|
||||
where
|
||||
'lua: 'fut,
|
||||
A: ToLuaMulti<'lua>,
|
||||
R: FromLuaMulti<'lua> + 'fut;
|
||||
|
||||
/// Gets the function associated to `key` from the table and executes it,
|
||||
/// passing the table itself along with `args` as function arguments.
|
||||
///
|
||||
|
@ -564,6 +582,25 @@ pub trait TableExt<'lua> {
|
|||
}
|
||||
|
||||
impl<'lua> TableExt<'lua> for Table<'lua> {
|
||||
fn call<A, R>(&self, args: A) -> Result<R>
|
||||
where
|
||||
A: ToLuaMulti<'lua>,
|
||||
R: FromLuaMulti<'lua>,
|
||||
{
|
||||
// Convert table to a function and call via pcall that respects the `__call` metamethod.
|
||||
Function(self.0.clone()).call(args)
|
||||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
fn call_async<'fut, A, R>(&self, args: A) -> LocalBoxFuture<'fut, Result<R>>
|
||||
where
|
||||
'lua: 'fut,
|
||||
A: ToLuaMulti<'lua>,
|
||||
R: FromLuaMulti<'lua> + 'fut,
|
||||
{
|
||||
Function(self.0.clone()).call_async(args)
|
||||
}
|
||||
|
||||
fn call_method<K, A, R>(&self, key: K, args: A) -> Result<R>
|
||||
where
|
||||
K: ToLua<'lua>,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use mlua::{Lua, Nil, Result, Table, TableExt, Value};
|
||||
use mlua::{Error, Lua, Nil, Result, Table, TableExt, Value};
|
||||
|
||||
#[test]
|
||||
fn test_set_get() -> Result<()> {
|
||||
|
@ -266,7 +266,12 @@ fn test_table_call() -> Result<()> {
|
|||
|
||||
lua.load(
|
||||
r#"
|
||||
table = {a = 1}
|
||||
table = {a = 1, b = 2}
|
||||
setmetatable(table, {
|
||||
__call = function(t, key)
|
||||
return "call_"..t[key]
|
||||
end
|
||||
})
|
||||
|
||||
function table.func(key)
|
||||
return "func_"..key
|
||||
|
@ -281,11 +286,19 @@ fn test_table_call() -> Result<()> {
|
|||
|
||||
let table: Table = lua.globals().get("table")?;
|
||||
|
||||
assert_eq!(table.call::<_, String>("b")?, "call_2");
|
||||
assert_eq!(table.call_function::<_, _, String>("func", "a")?, "func_a");
|
||||
assert_eq!(
|
||||
table.call_method::<_, _, String>("method", "a")?,
|
||||
"method_1"
|
||||
);
|
||||
|
||||
// Test calling non-callable table
|
||||
let table2 = lua.create_table()?;
|
||||
assert!(matches!(
|
||||
table2.call::<_, ()>(()),
|
||||
Err(Error::RuntimeError(_))
|
||||
));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue