diff options
author | Jesse Luehrs <doy@tozt.net> | 2021-12-25 20:53:05 -0500 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2021-12-25 20:57:05 -0500 |
commit | d5e7389247bdcdca7a620b99c8e63559e0abf29c (patch) | |
tree | 3d2b35607f277afda0a3563d4eadf38753728be7 /src | |
parent | 6513b4ae9c07d02aa5e4744538f745bf532988f0 (diff) | |
download | nbsh-d5e7389247bdcdca7a620b99c8e63559e0abf29c.tar.gz nbsh-d5e7389247bdcdca7a620b99c8e63559e0abf29c.zip |
make builtins async
Diffstat (limited to 'src')
-rw-r--r-- | src/state/history/builtins.rs | 57 | ||||
-rw-r--r-- | src/state/history/mod.rs | 2 |
2 files changed, 46 insertions, 13 deletions
diff --git a/src/state/history/builtins.rs b/src/state/history/builtins.rs index 6ca0228..83d8487 100644 --- a/src/state/history/builtins.rs +++ b/src/state/history/builtins.rs @@ -1,30 +1,63 @@ use std::os::unix::process::ExitStatusExt as _; -type Builtin = &'static (dyn Fn( - &crate::parse::Exe, - &super::ProcessEnv, -) -> std::process::ExitStatus - + Sync - + Send); +use std::future::Future; +use std::pin::Pin; + +// i hate all of this so much +type Builtin = Box< + dyn for<'a> Fn( + &'a crate::parse::Exe, + &'a super::ProcessEnv, + ) -> Pin< + Box< + dyn Future<Output = std::process::ExitStatus> + + Sync + + Send + + 'a, + >, + > + Sync + + Send, +>; + +fn box_builtin<F: 'static>(f: F) -> Builtin +where + F: for<'a> Fn( + &'a crate::parse::Exe, + &'a super::ProcessEnv, + ) -> Pin< + Box< + dyn Future<Output = std::process::ExitStatus> + + Sync + + Send + + 'a, + >, + > + Sync + + Send, +{ + Box::new(move |exe, env| Box::pin(f(exe, env))) +} -// i don't know how to do this without an as conversion -#[allow(clippy::as_conversions)] static BUILTINS: once_cell::sync::Lazy< std::collections::HashMap<&'static str, Builtin>, > = once_cell::sync::Lazy::new(|| { let mut builtins = std::collections::HashMap::new(); - builtins.insert("cd", &cd as Builtin); + builtins + .insert("cd", box_builtin(move |exe, env| Box::pin(cd(exe, env)))); builtins }); -pub fn run( +pub async fn run( exe: &crate::parse::Exe, env: &super::ProcessEnv, ) -> Option<async_std::process::ExitStatus> { - BUILTINS.get(exe.exe()).map(|f| f(exe, env)) + if let Some(f) = BUILTINS.get(exe.exe()) { + Some(f(exe, env).await) + } else { + None + } } -fn cd( +async fn cd( exe: &crate::parse::Exe, _: &super::ProcessEnv, ) -> async_std::process::ExitStatus { diff --git a/src/state/history/mod.rs b/src/state/history/mod.rs index 6d1f628..ea42d63 100644 --- a/src/state/history/mod.rs +++ b/src/state/history/mod.rs @@ -621,7 +621,7 @@ async fn run_exe( exe: &crate::parse::Exe, env: &ProcessEnv, ) -> async_std::process::ExitStatus { - if let Some(status) = builtins::run(exe, env) { + if let Some(status) = builtins::run(exe, env).await { return status; } |