Refactor `call_async()` functions to use static dispatch outside of traits
This commit is contained in:
parent
b05698d55b
commit
c1168d3ec1
28
src/chunk.rs
28
src/chunk.rs
|
@ -11,9 +11,6 @@ use crate::lua::Lua;
|
|||
use crate::table::Table;
|
||||
use crate::value::{FromLuaMulti, IntoLua, IntoLuaMulti};
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
use futures_util::future::{self, LocalBoxFuture};
|
||||
|
||||
/// Trait for types [loadable by Lua] and convertible to a [`Chunk`]
|
||||
///
|
||||
/// [loadable by Lua]: https://www.lua.org/manual/5.4/manual.html#3.3.2
|
||||
|
@ -312,8 +309,8 @@ impl<'lua, 'a> Chunk<'lua, 'a> {
|
|||
/// [`exec`]: #method.exec
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
pub fn exec_async(self) -> LocalBoxFuture<'lua, Result<()>> {
|
||||
self.call_async(())
|
||||
pub async fn exec_async(self) -> Result<()> {
|
||||
self.call_async(()).await
|
||||
}
|
||||
|
||||
/// Evaluate the chunk as either an expression or block.
|
||||
|
@ -344,17 +341,16 @@ impl<'lua, 'a> Chunk<'lua, 'a> {
|
|||
/// [`eval`]: #method.eval
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
pub fn eval_async<'fut, R>(self) -> LocalBoxFuture<'fut, Result<R>>
|
||||
pub async fn eval_async<R>(self) -> Result<R>
|
||||
where
|
||||
'lua: 'fut,
|
||||
R: FromLuaMulti<'lua> + 'fut,
|
||||
R: FromLuaMulti<'lua> + 'lua,
|
||||
{
|
||||
if self.detect_mode() == ChunkMode::Binary {
|
||||
self.call_async(())
|
||||
self.call_async(()).await
|
||||
} else if let Ok(function) = self.to_expression() {
|
||||
function.call_async(())
|
||||
function.call_async(()).await
|
||||
} else {
|
||||
self.call_async(())
|
||||
self.call_async(()).await
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -374,16 +370,12 @@ impl<'lua, 'a> Chunk<'lua, 'a> {
|
|||
/// [`call`]: #method.call
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
pub fn call_async<'fut, A, R>(self, args: A) -> LocalBoxFuture<'fut, Result<R>>
|
||||
pub async fn call_async<A, R>(self, args: A) -> Result<R>
|
||||
where
|
||||
'lua: 'fut,
|
||||
A: IntoLuaMulti<'lua>,
|
||||
R: FromLuaMulti<'lua> + 'fut,
|
||||
R: FromLuaMulti<'lua> + 'lua,
|
||||
{
|
||||
match self.into_function() {
|
||||
Ok(func) => func.call_async(args),
|
||||
Err(e) => Box::pin(future::err(e)),
|
||||
}
|
||||
self.into_function()?.call_async(args).await
|
||||
}
|
||||
|
||||
/// Load this chunk into a regular `Function`.
|
||||
|
|
|
@ -17,7 +17,7 @@ use crate::value::{FromLuaMulti, IntoLua, IntoLuaMulti};
|
|||
#[cfg(feature = "async")]
|
||||
use {
|
||||
crate::types::AsyncCallback,
|
||||
futures_util::future::{self, Future, LocalBoxFuture, TryFutureExt},
|
||||
futures_util::future::{self, Future},
|
||||
};
|
||||
|
||||
/// Handle to an internal Lua function.
|
||||
|
@ -77,7 +77,7 @@ pub struct FunctionInfo {
|
|||
#[cfg_attr(docsrs, doc(cfg(feature = "luau")))]
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct CoverageInfo {
|
||||
pub function: Option<std::string::String>,
|
||||
pub function: Option<String>,
|
||||
pub line_defined: i32,
|
||||
pub depth: i32,
|
||||
pub hits: Vec<i32>,
|
||||
|
@ -188,21 +188,18 @@ impl<'lua> Function<'lua> {
|
|||
/// [`AsyncThread`]: crate::AsyncThread
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
pub fn call_async<'fut, A, R>(&self, args: A) -> LocalBoxFuture<'fut, Result<R>>
|
||||
pub fn call_async<A, R>(&self, args: A) -> impl Future<Output = Result<R>> + 'lua
|
||||
where
|
||||
'lua: 'fut,
|
||||
A: IntoLuaMulti<'lua>,
|
||||
R: FromLuaMulti<'lua> + 'fut,
|
||||
R: FromLuaMulti<'lua> + 'lua,
|
||||
{
|
||||
let lua = self.0.lua;
|
||||
match lua.create_recycled_thread(self) {
|
||||
Ok(t) => {
|
||||
let mut t = t.into_async(args);
|
||||
t.set_recyclable(true);
|
||||
Box::pin(t)
|
||||
}
|
||||
Err(e) => Box::pin(future::err(e)),
|
||||
}
|
||||
let thread_res = lua.create_recycled_thread(self).map(|th| {
|
||||
let mut th = th.into_async(args);
|
||||
th.set_recyclable(true);
|
||||
th
|
||||
});
|
||||
async move { thread_res?.await }
|
||||
}
|
||||
|
||||
/// Returns a function that, when called, calls `self`, passing `args` as the first set of
|
||||
|
@ -544,12 +541,12 @@ impl OwnedFunction {
|
|||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
#[inline]
|
||||
pub fn call_async<'lua, A, R>(&'lua self, args: A) -> LocalBoxFuture<'lua, Result<R>>
|
||||
pub async fn call_async<'lua, A, R>(&'lua self, args: A) -> Result<R>
|
||||
where
|
||||
A: IntoLuaMulti<'lua>,
|
||||
R: FromLuaMulti<'lua> + 'lua,
|
||||
{
|
||||
self.to_ref().call_async(args)
|
||||
self.to_ref().call_async(args).await
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -604,7 +601,8 @@ impl<'lua> Function<'lua> {
|
|||
Ok(args) => args,
|
||||
Err(e) => return Box::pin(future::err(e)),
|
||||
};
|
||||
Box::pin(func(lua, args).and_then(move |ret| future::ready(ret.into_lua_multi(lua))))
|
||||
let fut = func(lua, args);
|
||||
Box::pin(async move { fut.await?.into_lua_multi(lua) })
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ use crate::{
|
|||
#[cfg(feature = "async")]
|
||||
use {
|
||||
crate::types::{AsyncCallback, AsyncCallbackUpvalue, AsyncPollUpvalue},
|
||||
futures_util::future::{self, Future, TryFutureExt},
|
||||
futures_util::future::{self, Future},
|
||||
futures_util::task::{noop_waker_ref, Context, Poll, Waker},
|
||||
};
|
||||
|
||||
|
@ -1619,7 +1619,8 @@ impl Lua {
|
|||
Ok(args) => args,
|
||||
Err(e) => return Box::pin(future::err(e)),
|
||||
};
|
||||
Box::pin(func(lua, args).and_then(move |ret| future::ready(ret.into_lua_multi(lua))))
|
||||
let fut = func(lua, args);
|
||||
Box::pin(async move { fut.await?.into_lua_multi(lua) })
|
||||
}))
|
||||
}
|
||||
|
||||
|
|
48
src/table.rs
48
src/table.rs
|
@ -888,11 +888,10 @@ pub trait TableExt<'lua>: Sealed {
|
|||
/// The metamethod is called with the table as its first argument, followed by the passed arguments.
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
fn call_async<'fut, A, R>(&self, args: A) -> LocalBoxFuture<'fut, Result<R>>
|
||||
fn call_async<A, R>(&self, args: A) -> LocalBoxFuture<'lua, Result<R>>
|
||||
where
|
||||
'lua: 'fut,
|
||||
A: IntoLuaMulti<'lua>,
|
||||
R: FromLuaMulti<'lua> + 'fut;
|
||||
R: FromLuaMulti<'lua> + 'lua;
|
||||
|
||||
/// Gets the function associated to `key` from the table and executes it,
|
||||
/// passing the table itself along with `args` as function arguments.
|
||||
|
@ -928,12 +927,11 @@ pub trait TableExt<'lua>: Sealed {
|
|||
/// This might invoke the `__index` metamethod.
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
fn call_async_method<'fut, K, A, R>(&self, key: K, args: A) -> LocalBoxFuture<'fut, Result<R>>
|
||||
fn call_async_method<K, A, R>(&self, key: K, args: A) -> LocalBoxFuture<'lua, Result<R>>
|
||||
where
|
||||
'lua: 'fut,
|
||||
K: IntoLua<'lua>,
|
||||
A: IntoLuaMulti<'lua>,
|
||||
R: FromLuaMulti<'lua> + 'fut;
|
||||
R: FromLuaMulti<'lua> + 'lua;
|
||||
|
||||
/// Gets the function associated to `key` from the table and asynchronously executes it,
|
||||
/// passing `args` as function arguments and returning Future.
|
||||
|
@ -943,16 +941,11 @@ pub trait TableExt<'lua>: Sealed {
|
|||
/// This might invoke the `__index` metamethod.
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
fn call_async_function<'fut, K, A, R>(
|
||||
&self,
|
||||
key: K,
|
||||
args: A,
|
||||
) -> LocalBoxFuture<'fut, Result<R>>
|
||||
fn call_async_function<K, A, R>(&self, key: K, args: A) -> LocalBoxFuture<'lua, Result<R>>
|
||||
where
|
||||
'lua: 'fut,
|
||||
K: IntoLua<'lua>,
|
||||
A: IntoLuaMulti<'lua>,
|
||||
R: FromLuaMulti<'lua> + 'fut;
|
||||
R: FromLuaMulti<'lua> + 'lua;
|
||||
}
|
||||
|
||||
impl<'lua> TableExt<'lua> for Table<'lua> {
|
||||
|
@ -966,13 +959,17 @@ impl<'lua> TableExt<'lua> for Table<'lua> {
|
|||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
fn call_async<'fut, A, R>(&self, args: A) -> LocalBoxFuture<'fut, Result<R>>
|
||||
fn call_async<A, R>(&self, args: A) -> LocalBoxFuture<'lua, Result<R>>
|
||||
where
|
||||
'lua: 'fut,
|
||||
A: IntoLuaMulti<'lua>,
|
||||
R: FromLuaMulti<'lua> + 'fut,
|
||||
R: FromLuaMulti<'lua> + 'lua,
|
||||
{
|
||||
Function(self.0.clone()).call_async(args)
|
||||
let args = match args.into_lua_multi(self.0.lua) {
|
||||
Ok(args) => args,
|
||||
Err(e) => return Box::pin(future::err(e)),
|
||||
};
|
||||
let func = Function(self.0.clone());
|
||||
Box::pin(async move { func.call_async(args).await })
|
||||
}
|
||||
|
||||
fn call_method<K, A, R>(&self, key: K, args: A) -> Result<R>
|
||||
|
@ -997,12 +994,11 @@ impl<'lua> TableExt<'lua> for Table<'lua> {
|
|||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
fn call_async_method<'fut, K, A, R>(&self, key: K, args: A) -> LocalBoxFuture<'fut, Result<R>>
|
||||
fn call_async_method<K, A, R>(&self, key: K, args: A) -> LocalBoxFuture<'lua, Result<R>>
|
||||
where
|
||||
'lua: 'fut,
|
||||
K: IntoLua<'lua>,
|
||||
A: IntoLuaMulti<'lua>,
|
||||
R: FromLuaMulti<'lua> + 'fut,
|
||||
R: FromLuaMulti<'lua> + 'lua,
|
||||
{
|
||||
let lua = self.0.lua;
|
||||
let mut args = match args.into_lua_multi(lua) {
|
||||
|
@ -1014,15 +1010,19 @@ impl<'lua> TableExt<'lua> for Table<'lua> {
|
|||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
fn call_async_function<'fut, K, A, R>(&self, key: K, args: A) -> LocalBoxFuture<'fut, Result<R>>
|
||||
fn call_async_function<K, A, R>(&self, key: K, args: A) -> LocalBoxFuture<'lua, Result<R>>
|
||||
where
|
||||
'lua: 'fut,
|
||||
K: IntoLua<'lua>,
|
||||
A: IntoLuaMulti<'lua>,
|
||||
R: FromLuaMulti<'lua> + 'fut,
|
||||
R: FromLuaMulti<'lua> + 'lua,
|
||||
{
|
||||
let lua = self.0.lua;
|
||||
let args = match args.into_lua_multi(lua) {
|
||||
Ok(args) => args,
|
||||
Err(e) => return Box::pin(future::err(e)),
|
||||
};
|
||||
match self.get::<_, Function>(key) {
|
||||
Ok(func) => func.call_async(args),
|
||||
Ok(func) => Box::pin(async move { func.call_async(args).await }),
|
||||
Err(e) => Box::pin(future::err(e)),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,11 +27,10 @@ pub trait AnyUserDataExt<'lua>: Sealed {
|
|||
/// The metamethod is called with the userdata as its first argument, followed by the passed arguments.
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
fn call_async<'fut, A, R>(&self, args: A) -> LocalBoxFuture<'fut, Result<R>>
|
||||
fn call_async<A, R>(&self, args: A) -> LocalBoxFuture<'lua, Result<R>>
|
||||
where
|
||||
'lua: 'fut,
|
||||
A: IntoLuaMulti<'lua>,
|
||||
R: FromLuaMulti<'lua> + 'fut;
|
||||
R: FromLuaMulti<'lua> + 'lua;
|
||||
|
||||
/// Calls the userdata method, assuming it has `__index` metamethod
|
||||
/// and a function associated to `name`.
|
||||
|
@ -48,15 +47,14 @@ pub trait AnyUserDataExt<'lua>: Sealed {
|
|||
/// This might invoke the `__index` metamethod.
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
fn call_async_method<'fut, A, R>(
|
||||
fn call_async_method<A, R>(
|
||||
&self,
|
||||
name: impl AsRef<str>,
|
||||
args: A,
|
||||
) -> LocalBoxFuture<'fut, Result<R>>
|
||||
) -> LocalBoxFuture<'lua, Result<R>>
|
||||
where
|
||||
'lua: 'fut,
|
||||
A: IntoLuaMulti<'lua>,
|
||||
R: FromLuaMulti<'lua> + 'fut;
|
||||
R: FromLuaMulti<'lua> + 'lua;
|
||||
|
||||
/// Gets the function associated to `key` from the table and executes it,
|
||||
/// passing `args` as function arguments.
|
||||
|
@ -78,15 +76,14 @@ pub trait AnyUserDataExt<'lua>: Sealed {
|
|||
/// This might invoke the `__index` metamethod.
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
fn call_async_function<'fut, A, R>(
|
||||
fn call_async_function<A, R>(
|
||||
&self,
|
||||
name: impl AsRef<str>,
|
||||
args: A,
|
||||
) -> LocalBoxFuture<'fut, Result<R>>
|
||||
) -> LocalBoxFuture<'lua, Result<R>>
|
||||
where
|
||||
'lua: 'fut,
|
||||
A: IntoLuaMulti<'lua>,
|
||||
R: FromLuaMulti<'lua> + 'fut;
|
||||
R: FromLuaMulti<'lua> + 'lua;
|
||||
}
|
||||
|
||||
impl<'lua> AnyUserDataExt<'lua> for AnyUserData<'lua> {
|
||||
|
@ -127,18 +124,24 @@ impl<'lua> AnyUserDataExt<'lua> for AnyUserData<'lua> {
|
|||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
fn call_async<'fut, A, R>(&self, args: A) -> LocalBoxFuture<'fut, Result<R>>
|
||||
fn call_async<A, R>(&self, args: A) -> LocalBoxFuture<'lua, Result<R>>
|
||||
where
|
||||
'lua: 'fut,
|
||||
A: IntoLuaMulti<'lua>,
|
||||
R: FromLuaMulti<'lua> + 'fut,
|
||||
R: FromLuaMulti<'lua> + 'lua,
|
||||
{
|
||||
let metatable = match self.get_metatable() {
|
||||
Ok(metatable) => metatable,
|
||||
Err(err) => return Box::pin(future::err(err)),
|
||||
};
|
||||
match metatable.get::<Value>(MetaMethod::Call) {
|
||||
Ok(Value::Function(func)) => func.call_async((self.clone(), args)),
|
||||
Ok(Value::Function(func)) => {
|
||||
let mut args = match args.into_lua_multi(self.0.lua) {
|
||||
Ok(args) => args,
|
||||
Err(e) => return Box::pin(future::err(e)),
|
||||
};
|
||||
args.push_front(Value::UserData(self.clone()));
|
||||
Box::pin(async move { func.call_async(args).await })
|
||||
}
|
||||
Ok(_) => Box::pin(future::err(Error::RuntimeError(
|
||||
"attempt to call a userdata value".to_string(),
|
||||
))),
|
||||
|
@ -155,15 +158,14 @@ impl<'lua> AnyUserDataExt<'lua> for AnyUserData<'lua> {
|
|||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
fn call_async_method<'fut, A, R>(
|
||||
fn call_async_method<A, R>(
|
||||
&self,
|
||||
name: impl AsRef<str>,
|
||||
args: A,
|
||||
) -> LocalBoxFuture<'fut, Result<R>>
|
||||
) -> LocalBoxFuture<'lua, Result<R>>
|
||||
where
|
||||
'lua: 'fut,
|
||||
A: IntoLuaMulti<'lua>,
|
||||
R: FromLuaMulti<'lua> + 'fut,
|
||||
R: FromLuaMulti<'lua> + 'lua,
|
||||
{
|
||||
self.call_async_function(name, (self.clone(), args))
|
||||
}
|
||||
|
@ -183,22 +185,28 @@ impl<'lua> AnyUserDataExt<'lua> for AnyUserData<'lua> {
|
|||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
fn call_async_function<'fut, A, R>(
|
||||
fn call_async_function<A, R>(
|
||||
&self,
|
||||
name: impl AsRef<str>,
|
||||
args: A,
|
||||
) -> LocalBoxFuture<'fut, Result<R>>
|
||||
) -> LocalBoxFuture<'lua, Result<R>>
|
||||
where
|
||||
'lua: 'fut,
|
||||
A: IntoLuaMulti<'lua>,
|
||||
R: FromLuaMulti<'lua> + 'fut,
|
||||
R: FromLuaMulti<'lua> + 'lua,
|
||||
{
|
||||
match self.get(name.as_ref()) {
|
||||
Ok(Value::Function(func)) => func.call_async(args),
|
||||
Ok(val) => Box::pin(future::err(Error::RuntimeError(format!(
|
||||
"attempt to call a {} value",
|
||||
val.type_name()
|
||||
)))),
|
||||
Ok(Value::Function(func)) => {
|
||||
let args = match args.into_lua_multi(self.0.lua) {
|
||||
Ok(args) => args,
|
||||
Err(e) => return Box::pin(future::err(e)),
|
||||
};
|
||||
Box::pin(async move { func.call_async(args).await })
|
||||
}
|
||||
Ok(val) => {
|
||||
let type_name = val.type_name();
|
||||
let msg = format!("attempt to call a {type_name} value");
|
||||
Box::pin(future::err(Error::RuntimeError(msg)))
|
||||
}
|
||||
Err(err) => Box::pin(future::err(err)),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue