From b95a6415d5c85fcbbc5dfc5983838530fdcff190 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Mon, 17 Jan 2022 18:06:14 -0500 Subject: make eval async --- src/parse/ast.rs | 38 +++++++++++++++++++++++--------------- src/parse/test_ast.rs | 7 +++++-- src/runner/mod.rs | 13 ++++++++----- 3 files changed, 36 insertions(+), 22 deletions(-) diff --git a/src/parse/ast.rs b/src/parse/ast.rs index 089c9f8..b7716df 100644 --- a/src/parse/ast.rs +++ b/src/parse/ast.rs @@ -90,13 +90,15 @@ pub struct Pipeline { } impl Pipeline { - pub fn eval(self, env: &Env) -> anyhow::Result { + pub async fn eval(self, env: &Env) -> anyhow::Result { Ok(super::Pipeline { exes: self .exes .into_iter() .map(|exe| exe.eval(env)) - .collect::>()?, + .collect::>() + .collect::>() + .await?, }) } @@ -122,8 +124,8 @@ struct Exe { } impl Exe { - fn eval(self, env: &Env) -> anyhow::Result { - let exe = self.exe.eval(env)?; + async fn eval(self, env: &Env) -> anyhow::Result { + let exe = self.exe.eval(env).await?; assert_eq!(exe.len(), 1); // TODO let exe = &exe[0]; Ok(super::Exe { @@ -131,8 +133,12 @@ impl Exe { args: self .args .into_iter() - .map(|arg| arg.eval(env).map(IntoIterator::into_iter)) - .collect::, _>>()? + .map(|arg| async { + arg.eval(env).await.map(IntoIterator::into_iter) + }) + .collect::>() + .collect::, _>>() + .await? .into_iter() .flatten() .collect(), @@ -140,7 +146,9 @@ impl Exe { .redirects .into_iter() .map(|arg| arg.eval(env)) - .collect::>()?, + .collect::>() + .collect::>() + .await?, }) } @@ -218,7 +226,7 @@ impl Word { } } - pub fn eval(self, env: &Env) -> anyhow::Result> { + pub async fn eval(self, env: &Env) -> anyhow::Result> { let mut opts = glob::MatchOptions::new(); opts.require_literal_separator = true; opts.require_literal_leading_dot = true; @@ -264,7 +272,7 @@ impl Word { match part { WordPart::Alternation(_) => unreachable!(), WordPart::Bareword(_) => { - let part = part.eval(env); + let part = part.eval(env).await; s.push_str(&part); pat.push_str(&part); if part.contains(&['*', '?', '['][..]) { @@ -274,7 +282,7 @@ impl Word { WordPart::Var(_) | WordPart::DoubleQuoted(_) | WordPart::SingleQuoted(_) => { - let part = part.eval(env); + let part = part.eval(env).await; s.push_str(&part); pat.push_str(&glob::Pattern::escape(&part)); } @@ -357,7 +365,7 @@ impl WordPart { }) } - fn eval(self, env: &Env) -> String { + async fn eval(self, env: &Env) -> String { match self { Self::Alternation(_) => unreachable!(), Self::Var(name) => { @@ -399,25 +407,25 @@ impl Redirect { Self { from, to, dir } } - fn eval(self, env: &Env) -> anyhow::Result { + async fn eval(self, env: &Env) -> anyhow::Result { let to = if self.to.parts.len() == 1 { if let WordPart::Bareword(s) = &self.to.parts[0] { if let Some(fd) = s.strip_prefix('&') { super::RedirectTarget::Fd(parse_fd(fd)) } else { - let to = self.to.eval(env)?; + let to = self.to.eval(env).await?; assert_eq!(to.len(), 1); // TODO let to = &to[0]; super::RedirectTarget::File(std::path::PathBuf::from(to)) } } else { - let to = self.to.eval(env)?; + let to = self.to.eval(env).await?; assert_eq!(to.len(), 1); // TODO let to = &to[0]; super::RedirectTarget::File(std::path::PathBuf::from(to)) } } else { - let to = self.to.eval(env)?; + let to = self.to.eval(env).await?; assert_eq!(to.len(), 1); // TODO let to = &to[0]; super::RedirectTarget::File(std::path::PathBuf::from(to)) diff --git a/src/parse/test_ast.rs b/src/parse/test_ast.rs index f762615..09d772b 100644 --- a/src/parse/test_ast.rs +++ b/src/parse/test_ast.rs @@ -156,7 +156,10 @@ macro_rules! eval_eq { | Command::While(p) => p, _ => continue, }; - assert_eq!(pipeline.eval(&$env).unwrap(), expected.remove(0)); + assert_eq!( + async_std::task::block_on(pipeline.eval(&$env)).unwrap(), + expected.remove(0) + ); } }}; } @@ -172,7 +175,7 @@ macro_rules! eval_fails { } _ => continue, }; - if pipeline.eval(&$env).is_err() { + if async_std::task::block_on(pipeline.eval(&$env)).is_err() { fail = true; } } diff --git a/src/runner/mod.rs b/src/runner/mod.rs index 6d3710e..1633ba0 100644 --- a/src/runner/mod.rs +++ b/src/runner/mod.rs @@ -147,10 +147,13 @@ async fn run_commands( if stack.should_execute() { list.clone() .into_iter() - .map(|w| { - w.eval(env).map(IntoIterator::into_iter) + .map(|w| async { + w.eval(env) + .await + .map(IntoIterator::into_iter) }) - .collect::, _>>()? + .collect::>() + .collect::, _>>().await? .into_iter() .flatten() .collect() @@ -247,6 +250,7 @@ async fn run_pipeline( io.set_stderr(stderr); let pwd = env.pwd().to_path_buf(); + let pipeline = pipeline.eval(env).await?; let (children, pg) = spawn_children(pipeline, env, &io)?; let status = wait_children(children, pg, env, &io, shell_write).await; set_foreground_pg(nix::unistd::getpid())?; @@ -270,11 +274,10 @@ async fn write_event( } fn spawn_children<'a>( - pipeline: crate::parse::ast::Pipeline, + pipeline: crate::parse::Pipeline, env: &'a Env, io: &builtins::Io, ) -> anyhow::Result<(Vec>, Option)> { - let pipeline = pipeline.eval(env)?; let mut cmds: Vec<_> = pipeline .into_exes() .map(|exe| Command::new(exe, io.clone())) -- cgit v1.2.3-54-g00ecf