diff options
Diffstat (limited to 'src/state/history/builtins.rs')
-rw-r--r-- | src/state/history/builtins.rs | 57 |
1 files changed, 45 insertions, 12 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 { |