Add TableExt trait with call_method/function methods
This commit is contained in:
parent
d8897d867b
commit
ee08050c1f
|
@ -66,7 +66,7 @@ pub use crate::lua::{Chunk, Lua};
|
||||||
pub use crate::multi::Variadic;
|
pub use crate::multi::Variadic;
|
||||||
pub use crate::stdlib::StdLib;
|
pub use crate::stdlib::StdLib;
|
||||||
pub use crate::string::String;
|
pub use crate::string::String;
|
||||||
pub use crate::table::{Table, TablePairs, TableSequence};
|
pub use crate::table::{Table, TableExt, TablePairs, TableSequence};
|
||||||
pub use crate::thread::{Thread, ThreadStatus};
|
pub use crate::thread::{Thread, ThreadStatus};
|
||||||
pub use crate::types::{Integer, LightUserData, Number, RegistryKey};
|
pub use crate::types::{Integer, LightUserData, Number, RegistryKey};
|
||||||
pub use crate::userdata::{AnyUserData, MetaMethod, UserData, UserDataMethods};
|
pub use crate::userdata::{AnyUserData, MetaMethod, UserData, UserDataMethods};
|
||||||
|
|
|
@ -6,9 +6,9 @@ pub use crate::{
|
||||||
Function as LuaFunction, Integer as LuaInteger, LightUserData as LuaLightUserData, Lua,
|
Function as LuaFunction, Integer as LuaInteger, LightUserData as LuaLightUserData, Lua,
|
||||||
MetaMethod as LuaMetaMethod, MultiValue as LuaMultiValue, Nil as LuaNil, Number as LuaNumber,
|
MetaMethod as LuaMetaMethod, MultiValue as LuaMultiValue, Nil as LuaNil, Number as LuaNumber,
|
||||||
RegistryKey as LuaRegistryKey, Result as LuaResult, String as LuaString, Table as LuaTable,
|
RegistryKey as LuaRegistryKey, Result as LuaResult, String as LuaString, Table as LuaTable,
|
||||||
TablePairs as LuaTablePairs, TableSequence as LuaTableSequence, Thread as LuaThread,
|
TableExt as LuaTableExt, TablePairs as LuaTablePairs, TableSequence as LuaTableSequence,
|
||||||
ThreadStatus as LuaThreadStatus, ToLua, ToLuaMulti, UserData as LuaUserData,
|
Thread as LuaThread, ThreadStatus as LuaThreadStatus, ToLua, ToLuaMulti,
|
||||||
UserDataMethods as LuaUserDataMethods, Value as LuaValue,
|
UserData as LuaUserData, UserDataMethods as LuaUserDataMethods, Value as LuaValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "async")]
|
#[cfg(feature = "async")]
|
||||||
|
|
134
src/table.rs
134
src/table.rs
|
@ -8,6 +8,12 @@ use crate::types::{Integer, LuaRef};
|
||||||
use crate::util::{assert_stack, protect_lua, protect_lua_closure, StackGuard};
|
use crate::util::{assert_stack, protect_lua, protect_lua_closure, StackGuard};
|
||||||
use crate::value::{FromLua, FromLuaMulti, Nil, ToLua, ToLuaMulti, Value};
|
use crate::value::{FromLua, FromLuaMulti, Nil, ToLua, ToLuaMulti, Value};
|
||||||
|
|
||||||
|
#[cfg(feature = "async")]
|
||||||
|
use {
|
||||||
|
futures_core::future::LocalBoxFuture,
|
||||||
|
futures_util::future::{self, FutureExt},
|
||||||
|
};
|
||||||
|
|
||||||
/// Handle to an internal Lua table.
|
/// Handle to an internal Lua table.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Table<'lua>(pub(crate) LuaRef<'lua>);
|
pub struct Table<'lua>(pub(crate) LuaRef<'lua>);
|
||||||
|
@ -134,7 +140,10 @@ impl<'lua> Table<'lua> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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 as the first argument.
|
/// passing the table itself along with `args` as function arguments.
|
||||||
|
///
|
||||||
|
/// This function is deprecated since 0.3.1 in favor of [`call_method`]
|
||||||
|
/// in the `TableExt` trait.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -154,6 +163,9 @@ impl<'lua> Table<'lua> {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// This might invoke the `__index` metamethod.
|
/// This might invoke the `__index` metamethod.
|
||||||
|
///
|
||||||
|
/// [`call_method`]: trait.TableExt.html#tymethod.call_method
|
||||||
|
#[deprecated(since = "0.3.1", note = "Please use `call_method` instead")]
|
||||||
pub fn call<K, A, R>(&self, key: K, args: A) -> Result<R>
|
pub fn call<K, A, R>(&self, key: K, args: A) -> Result<R>
|
||||||
where
|
where
|
||||||
K: ToLua<'lua>,
|
K: ToLua<'lua>,
|
||||||
|
@ -262,7 +274,7 @@ impl<'lua> Table<'lua> {
|
||||||
V::from_lua(value, lua)
|
V::from_lua(value, lua)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Inserts element value at position idx to the table, shifting up the elements from table[idx].
|
/// Inserts element value at position `idx` to the table, shifting up the elements from `table[idx]`.
|
||||||
/// The worst case complexity is O(n), where n is the table length.
|
/// The worst case complexity is O(n), where n is the table length.
|
||||||
pub fn raw_insert<V: ToLua<'lua>>(&self, idx: Integer, value: V) -> Result<()> {
|
pub fn raw_insert<V: ToLua<'lua>>(&self, idx: Integer, value: V) -> Result<()> {
|
||||||
let lua = self.0.lua;
|
let lua = self.0.lua;
|
||||||
|
@ -292,11 +304,11 @@ impl<'lua> Table<'lua> {
|
||||||
|
|
||||||
/// Removes a key from the table.
|
/// Removes a key from the table.
|
||||||
///
|
///
|
||||||
/// If `key` is an integer, mlua shifts down the elements from table[key+1],
|
/// If `key` is an integer, mlua shifts down the elements from `table[key+1]`,
|
||||||
/// and erases element table[key]. The complexity is O(n) in worst case,
|
/// and erases element `table[key]`. The complexity is O(n) in worst case,
|
||||||
/// where n is the table length.
|
/// where n is the table length.
|
||||||
///
|
///
|
||||||
/// For othey key types this is equivalent to setting table[key] = nil.
|
/// For othey key types this is equivalent to setting `table[key] = nil`.
|
||||||
pub fn raw_remove<K: ToLua<'lua>>(&self, key: K) -> Result<()> {
|
pub fn raw_remove<K: ToLua<'lua>>(&self, key: K) -> Result<()> {
|
||||||
let lua = self.0.lua;
|
let lua = self.0.lua;
|
||||||
let key = key.to_lua(lua)?;
|
let key = key.to_lua(lua)?;
|
||||||
|
@ -494,6 +506,118 @@ 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> {
|
||||||
|
/// Gets the function associated to `key` from the table and executes it,
|
||||||
|
/// passing the table itself along with `args` as function arguments.
|
||||||
|
///
|
||||||
|
/// This is a shortcut for
|
||||||
|
/// `table.get::<_, Function>(key)?.call((table.clone(), arg1, ..., argN))`
|
||||||
|
///
|
||||||
|
/// This might invoke the `__index` metamethod.
|
||||||
|
fn call_method<K, A, R>(&self, key: K, args: A) -> Result<R>
|
||||||
|
where
|
||||||
|
K: ToLua<'lua>,
|
||||||
|
A: ToLuaMulti<'lua>,
|
||||||
|
R: FromLuaMulti<'lua>;
|
||||||
|
|
||||||
|
/// Gets the function associated to `key` from the table and executes it,
|
||||||
|
/// passing `args` as function arguments.
|
||||||
|
///
|
||||||
|
/// This is a shortcut for
|
||||||
|
/// `table.get::<_, Function>(key)?.call(args)`
|
||||||
|
///
|
||||||
|
/// This might invoke the `__index` metamethod.
|
||||||
|
fn call_function<K, A, R>(&self, key: K, args: A) -> Result<R>
|
||||||
|
where
|
||||||
|
K: ToLua<'lua>,
|
||||||
|
A: ToLuaMulti<'lua>,
|
||||||
|
R: FromLuaMulti<'lua>;
|
||||||
|
|
||||||
|
/// Gets the function associated to `key` from the table and asynchronously executes it,
|
||||||
|
/// passing the table itself along with `args` as function arguments and returning Future.
|
||||||
|
///
|
||||||
|
/// This might invoke the `__index` metamethod.
|
||||||
|
#[cfg(feature = "async")]
|
||||||
|
fn call_async_method<'fut, K, A, R>(&self, key: K, args: A) -> LocalBoxFuture<'fut, Result<R>>
|
||||||
|
where
|
||||||
|
'lua: 'fut,
|
||||||
|
K: ToLua<'lua>,
|
||||||
|
A: ToLuaMulti<'lua>,
|
||||||
|
R: FromLuaMulti<'lua> + 'fut;
|
||||||
|
|
||||||
|
/// Gets the function associated to `key` from the table and asynchronously executes it,
|
||||||
|
/// passing `args` as function arguments and returning Future.
|
||||||
|
///
|
||||||
|
/// This might invoke the `__index` metamethod.
|
||||||
|
#[cfg(feature = "async")]
|
||||||
|
fn call_async_function<'fut, K, A, R>(
|
||||||
|
&self,
|
||||||
|
key: K,
|
||||||
|
args: A,
|
||||||
|
) -> LocalBoxFuture<'fut, Result<R>>
|
||||||
|
where
|
||||||
|
'lua: 'fut,
|
||||||
|
K: ToLua<'lua>,
|
||||||
|
A: ToLuaMulti<'lua>,
|
||||||
|
R: FromLuaMulti<'lua> + 'fut;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'lua> TableExt<'lua> for Table<'lua> {
|
||||||
|
fn call_method<K, A, R>(&self, key: K, args: A) -> Result<R>
|
||||||
|
where
|
||||||
|
K: ToLua<'lua>,
|
||||||
|
A: ToLuaMulti<'lua>,
|
||||||
|
R: FromLuaMulti<'lua>,
|
||||||
|
{
|
||||||
|
let lua = self.0.lua;
|
||||||
|
let mut args = args.to_lua_multi(lua)?;
|
||||||
|
args.push_front(Value::Table(self.clone()));
|
||||||
|
self.get::<_, Function>(key)?.call(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call_function<K, A, R>(&self, key: K, args: A) -> Result<R>
|
||||||
|
where
|
||||||
|
K: ToLua<'lua>,
|
||||||
|
A: ToLuaMulti<'lua>,
|
||||||
|
R: FromLuaMulti<'lua>,
|
||||||
|
{
|
||||||
|
self.get::<_, Function>(key)?.call(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "async")]
|
||||||
|
fn call_async_method<'fut, K, A, R>(&self, key: K, args: A) -> LocalBoxFuture<'fut, Result<R>>
|
||||||
|
where
|
||||||
|
'lua: 'fut,
|
||||||
|
K: ToLua<'lua>,
|
||||||
|
A: ToLuaMulti<'lua>,
|
||||||
|
R: FromLuaMulti<'lua> + 'fut,
|
||||||
|
{
|
||||||
|
let lua = self.0.lua;
|
||||||
|
let mut args = match args.to_lua_multi(lua) {
|
||||||
|
Ok(args) => args,
|
||||||
|
Err(e) => return future::err(e).boxed_local(),
|
||||||
|
};
|
||||||
|
args.push_front(Value::Table(self.clone()));
|
||||||
|
self.call_async_function(key, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "async")]
|
||||||
|
fn call_async_function<'fut, K, A, R>(&self, key: K, args: A) -> LocalBoxFuture<'fut, Result<R>>
|
||||||
|
where
|
||||||
|
'lua: 'fut,
|
||||||
|
K: ToLua<'lua>,
|
||||||
|
A: ToLuaMulti<'lua>,
|
||||||
|
R: FromLuaMulti<'lua> + 'fut,
|
||||||
|
{
|
||||||
|
let func = match self.get::<_, Function>(key) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(e) => return future::err(e).boxed_local(),
|
||||||
|
};
|
||||||
|
func.call_async(args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An iterator over the pairs of a Lua table.
|
/// An iterator over the pairs of a Lua table.
|
||||||
///
|
///
|
||||||
/// This struct is created by the [`Table::pairs`] method.
|
/// This struct is created by the [`Table::pairs`] method.
|
||||||
|
|
Loading…
Reference in New Issue