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.
|
/// An extension trait for `Table`s that provides a variety of convenient functionality.
|
||||||
pub trait TableExt<'lua> {
|
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,
|
/// Gets the function associated to `key` from the table and executes it,
|
||||||
/// passing the table itself along with `args` as function arguments.
|
/// 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> {
|
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>
|
fn call_method<K, A, R>(&self, key: K, args: A) -> Result<R>
|
||||||
where
|
where
|
||||||
K: ToLua<'lua>,
|
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]
|
#[test]
|
||||||
fn test_set_get() -> Result<()> {
|
fn test_set_get() -> Result<()> {
|
||||||
|
@ -266,7 +266,12 @@ fn test_table_call() -> Result<()> {
|
||||||
|
|
||||||
lua.load(
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
table = {a = 1}
|
table = {a = 1, b = 2}
|
||||||
|
setmetatable(table, {
|
||||||
|
__call = function(t, key)
|
||||||
|
return "call_"..t[key]
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
function table.func(key)
|
function table.func(key)
|
||||||
return "func_"..key
|
return "func_"..key
|
||||||
|
@ -281,11 +286,19 @@ fn test_table_call() -> Result<()> {
|
||||||
|
|
||||||
let table: Table = lua.globals().get("table")?;
|
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_function::<_, _, String>("func", "a")?, "func_a");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
table.call_method::<_, _, String>("method", "a")?,
|
table.call_method::<_, _, String>("method", "a")?,
|
||||||
"method_1"
|
"method_1"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Test calling non-callable table
|
||||||
|
let table2 = lua.create_table()?;
|
||||||
|
assert!(matches!(
|
||||||
|
table2.call::<_, ()>(()),
|
||||||
|
Err(Error::RuntimeError(_))
|
||||||
|
));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue