Separate sync and async fns again (#242)
This commit is contained in:
parent
5313d0cfab
commit
825ccf0986
1 changed files with 70 additions and 47 deletions
|
@ -25,42 +25,37 @@ pub mod util;
|
||||||
|
|
||||||
/// Attempts to run any function.
|
/// Attempts to run any function.
|
||||||
pub async fn run(ctx: &Context<'_>, name: &str, args: Vec<Value>) -> Result<Value, Error> {
|
pub async fn run(ctx: &Context<'_>, name: &str, args: Vec<Value>) -> Result<Value, Error> {
|
||||||
// Wrappers return a function as opposed to a value so that the dispatch! method can always
|
if name.starts_with("http")
|
||||||
// perform a function call.
|
|| (name.starts_with("crypto") && (name.ends_with("compare") || name.ends_with("generate")))
|
||||||
#[cfg(feature = "parallel")]
|
{
|
||||||
fn cpu_intensive<R: Send + 'static>(
|
asynchronous(ctx, name, args).await
|
||||||
function: impl FnOnce() -> R + Send + 'static,
|
} else {
|
||||||
) -> impl FnOnce() -> executor::Task<R> {
|
synchronous(ctx, name, args)
|
||||||
|| crate::exe::spawn(async move { function() })
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "parallel"))]
|
// Each function is specified by its name (a string literal) followed by its path. The path
|
||||||
fn cpu_intensive<R: Send + 'static>(
|
// may be followed by one parenthesized argument, e.g. ctx, which is passed to the function
|
||||||
function: impl FnOnce() -> R + Send + 'static,
|
// before the remainder of the arguments. The path may be followed by `.await` to signify that
|
||||||
) -> impl FnOnce() -> std::future::Ready<R> {
|
// it is `async`. Finally, the path may be prefixed by a parenthesized wrapper function e.g.
|
||||||
|| std::future::ready(function())
|
// `cpu_intensive`.
|
||||||
}
|
macro_rules! dispatch {
|
||||||
|
($name: ident, $args: ident, $($function_name: literal => $(($wrapper: tt))* $($function_path: ident)::+ $(($ctx_arg: expr))* $(.$await:tt)*,)+) => {
|
||||||
macro_rules! dispatch {
|
{
|
||||||
($name: ident, $args: ident, $($function_name: literal => $(($wrapper: tt))* $($function_path: ident)::+ $(($ctx_arg: expr))* $(.$await:tt)*,)+) => {
|
match $name {
|
||||||
{
|
$($function_name => {
|
||||||
match $name {
|
let args = args::FromArgs::from_args($name, $args)?;
|
||||||
$($function_name => {
|
#[allow(clippy::redundant_closure_call)]
|
||||||
let args = args::FromArgs::from_args($name, $args)?;
|
$($wrapper)*(|| $($function_path)::+($($ctx_arg,)* args))()$(.$await)*
|
||||||
#[allow(clippy::redundant_closure_call)]
|
},)+
|
||||||
$($wrapper)*(|| $($function_path)::+($($ctx_arg,)* args))()$(.$await)*
|
_ => unreachable!()
|
||||||
},)+
|
|
||||||
_ => unreachable!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Each function is specified by its name (a string literal) followed by its path. The path
|
/// Attempts to run any synchronous function.
|
||||||
// may be followed by one parenthesized argument, e.g. ctx, which is passed to the function
|
pub fn synchronous(ctx: &Context<'_>, name: &str, args: Vec<Value>) -> Result<Value, Error> {
|
||||||
// before the remainder of the arguments. The path may be followed by `.await` to signify that
|
|
||||||
// it is `async`. Finally, the path may be prefixed by a parenthesized wrapper function e.g.
|
|
||||||
// `cpu_intensive`.
|
|
||||||
dispatch!(
|
dispatch!(
|
||||||
name,
|
name,
|
||||||
args,
|
args,
|
||||||
|
@ -81,14 +76,6 @@ pub async fn run(ctx: &Context<'_>, name: &str, args: Vec<Value>) -> Result<Valu
|
||||||
"crypto::sha1" => crypto::sha1,
|
"crypto::sha1" => crypto::sha1,
|
||||||
"crypto::sha256" => crypto::sha256,
|
"crypto::sha256" => crypto::sha256,
|
||||||
"crypto::sha512" => crypto::sha512,
|
"crypto::sha512" => crypto::sha512,
|
||||||
"crypto::argon2::compare" => (cpu_intensive) crypto::argon2::cmp.await,
|
|
||||||
"crypto::argon2::generate" => (cpu_intensive) crypto::argon2::gen.await,
|
|
||||||
"crypto::bcrypt::compare" => (cpu_intensive) crypto::bcrypt::cmp.await,
|
|
||||||
"crypto::bcrypt::generate" => (cpu_intensive) crypto::bcrypt::gen.await,
|
|
||||||
"crypto::pbkdf2::compare" => (cpu_intensive) crypto::pbkdf2::cmp.await,
|
|
||||||
"crypto::pbkdf2::generate" => (cpu_intensive) crypto::pbkdf2::gen.await,
|
|
||||||
"crypto::scrypt::compare" => (cpu_intensive) crypto::scrypt::cmp.await,
|
|
||||||
"crypto::scrypt::generate" => (cpu_intensive) crypto::scrypt::gen.await,
|
|
||||||
//
|
//
|
||||||
"geo::area" => geo::area,
|
"geo::area" => geo::area,
|
||||||
"geo::bearing" => geo::bearing,
|
"geo::bearing" => geo::bearing,
|
||||||
|
@ -97,13 +84,6 @@ pub async fn run(ctx: &Context<'_>, name: &str, args: Vec<Value>) -> Result<Valu
|
||||||
"geo::hash::decode" => geo::hash::decode,
|
"geo::hash::decode" => geo::hash::decode,
|
||||||
"geo::hash::encode" => geo::hash::encode,
|
"geo::hash::encode" => geo::hash::encode,
|
||||||
//
|
//
|
||||||
"http::head" => http::head.await,
|
|
||||||
"http::get" => http::get.await,
|
|
||||||
"http::put" => http::put.await,
|
|
||||||
"http::post" => http::post.await,
|
|
||||||
"http::patch" => http::patch.await,
|
|
||||||
"http::delete" => http::delete.await,
|
|
||||||
//
|
|
||||||
"is::alphanum" => is::alphanum,
|
"is::alphanum" => is::alphanum,
|
||||||
"is::alpha" => is::alpha,
|
"is::alpha" => is::alpha,
|
||||||
"is::ascii" => is::ascii,
|
"is::ascii" => is::ascii,
|
||||||
|
@ -218,3 +198,46 @@ pub async fn run(ctx: &Context<'_>, name: &str, args: Vec<Value>) -> Result<Valu
|
||||||
"type::thing" => r#type::thing,
|
"type::thing" => r#type::thing,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempts to run any asynchronous function.
|
||||||
|
pub async fn asynchronous(
|
||||||
|
_ctx: &Context<'_>,
|
||||||
|
name: &str,
|
||||||
|
args: Vec<Value>,
|
||||||
|
) -> Result<Value, Error> {
|
||||||
|
// Wrappers return a function as opposed to a value so that the dispatch! method can always
|
||||||
|
// perform a function call.
|
||||||
|
#[cfg(feature = "parallel")]
|
||||||
|
fn cpu_intensive<R: Send + 'static>(
|
||||||
|
function: impl FnOnce() -> R + Send + 'static,
|
||||||
|
) -> impl FnOnce() -> executor::Task<R> {
|
||||||
|
|| crate::exe::spawn(async move { function() })
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "parallel"))]
|
||||||
|
fn cpu_intensive<R: Send + 'static>(
|
||||||
|
function: impl FnOnce() -> R + Send + 'static,
|
||||||
|
) -> impl FnOnce() -> std::future::Ready<R> {
|
||||||
|
|| std::future::ready(function())
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch!(
|
||||||
|
name,
|
||||||
|
args,
|
||||||
|
"crypto::argon2::compare" => (cpu_intensive) crypto::argon2::cmp.await,
|
||||||
|
"crypto::argon2::generate" => (cpu_intensive) crypto::argon2::gen.await,
|
||||||
|
"crypto::bcrypt::compare" => (cpu_intensive) crypto::bcrypt::cmp.await,
|
||||||
|
"crypto::bcrypt::generate" => (cpu_intensive) crypto::bcrypt::gen.await,
|
||||||
|
"crypto::pbkdf2::compare" => (cpu_intensive) crypto::pbkdf2::cmp.await,
|
||||||
|
"crypto::pbkdf2::generate" => (cpu_intensive) crypto::pbkdf2::gen.await,
|
||||||
|
"crypto::scrypt::compare" => (cpu_intensive) crypto::scrypt::cmp.await,
|
||||||
|
"crypto::scrypt::generate" => (cpu_intensive) crypto::scrypt::gen.await,
|
||||||
|
//
|
||||||
|
"http::head" => http::head.await,
|
||||||
|
"http::get" => http::get.await,
|
||||||
|
"http::put" => http::put.await,
|
||||||
|
"http::post" => http::post.await,
|
||||||
|
"http::patch" => http::patch.await,
|
||||||
|
"http::delete" => http::delete.await,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue