conch_runtime_pshaw/spawn/
func_exec.rs

1use crate::env::{FunctionEnvironment, FunctionFrameEnvironment, SetArgumentsEnvironment};
2use crate::{ExitStatus, Spawn};
3use futures_core::future::BoxFuture;
4
5/// Creates a future adapter that will attempt to execute a function (if it has
6/// been defined) with a given set of arguments.
7pub async fn function<S, A, E: ?Sized>(
8    name: &E::FnName,
9    args: A,
10    env: &mut E,
11) -> Option<Result<BoxFuture<'static, ExitStatus>, S::Error>>
12where
13    E: FunctionEnvironment<Fn = S> + FunctionFrameEnvironment + SetArgumentsEnvironment,
14    E::Args: From<A>,
15    S: Clone + Spawn<E>,
16{
17    match env.function(name).cloned() {
18        Some(func) => Some(function_body(func, args, env).await),
19        None => None,
20    }
21}
22
23/// Creates a future adapter that will execute a function body with the given set of arguments.
24pub async fn function_body<S, A, E: ?Sized>(
25    body: S,
26    args: A,
27    env: &mut E,
28) -> Result<BoxFuture<'static, ExitStatus>, S::Error>
29where
30    S: Spawn<E>,
31    E: FunctionFrameEnvironment + SetArgumentsEnvironment,
32    E::Args: From<A>,
33{
34    do_function_body(body, args.into(), env).await
35}
36
37async fn do_function_body<S, E: ?Sized>(
38    body: S,
39    args: E::Args,
40    env: &mut E,
41) -> Result<BoxFuture<'static, ExitStatus>, S::Error>
42where
43    S: Spawn<E>,
44    E: FunctionFrameEnvironment + SetArgumentsEnvironment,
45{
46    env.push_fn_frame();
47    let old_args = env.set_args(args);
48
49    let ret = body.spawn(env).await;
50
51    env.set_args(old_args);
52    env.pop_fn_frame();
53    ret
54}