summaryrefslogtreecommitdiffstats
path: root/src/builtins/command.rs
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2022-01-03 06:36:44 -0500
committerJesse Luehrs <doy@tozt.net>2022-01-03 06:37:17 -0500
commitae132f478c6cfc6ffb062fecd7efb42ac4e5d804 (patch)
treed91ea9575cdd6e3509d67bcc1373ac3afba3dccb /src/builtins/command.rs
parent4142936f657004f88e259583136f25f566b0b1c0 (diff)
downloadnbsh-ae132f478c6cfc6ffb062fecd7efb42ac4e5d804.tar.gz
nbsh-ae132f478c6cfc6ffb062fecd7efb42ac4e5d804.zip
stop cloning exe and env all over the place
Diffstat (limited to 'src/builtins/command.rs')
-rw-r--r--src/builtins/command.rs57
1 files changed, 36 insertions, 21 deletions
diff --git a/src/builtins/command.rs b/src/builtins/command.rs
index 6dfa56c..2ea7f18 100644
--- a/src/builtins/command.rs
+++ b/src/builtins/command.rs
@@ -8,12 +8,16 @@ pub struct Command {
}
impl Command {
- pub fn new(exe: &crate::parse::Exe) -> Option<Self> {
- super::BUILTINS.get(exe.exe()).map(|f| Self {
- exe: exe.clone(),
- f,
- io: Io::new(),
- })
+ pub fn new(exe: crate::parse::Exe) -> Result<Self, crate::parse::Exe> {
+ if let Some(f) = super::BUILTINS.get(exe.exe()) {
+ Ok(Self {
+ exe,
+ f,
+ io: Io::new(),
+ })
+ } else {
+ Err(exe)
+ }
}
pub fn stdin(&mut self, fh: std::fs::File) {
@@ -37,7 +41,7 @@ impl Command {
pub fn spawn(self, env: &crate::env::Env) -> anyhow::Result<Child> {
let Self { f, exe, io } = self;
- (f)(&exe, env, io)
+ (f)(exe, env, io)
}
}
@@ -186,24 +190,25 @@ impl Drop for Io {
}
}
-pub struct Child {
+pub struct Child<'a> {
fut: std::pin::Pin<
Box<
dyn std::future::Future<Output = std::process::ExitStatus>
+ Sync
- + Send,
+ + Send
+ + 'a,
>,
>,
- wrapped_child: Option<Box<crate::pipeline::Child>>,
+ wrapped_child: Option<Box<crate::pipeline::Child<'a>>>,
}
-impl Child {
+impl<'a> Child<'a> {
pub fn new_fut<F>(fut: F) -> Self
where
F: std::future::Future<Output = std::process::ExitStatus>
+ Sync
+ Send
- + 'static,
+ + 'a,
{
Self {
fut: Box::pin(fut),
@@ -211,7 +216,7 @@ impl Child {
}
}
- pub fn new_wrapped(child: crate::pipeline::Child) -> Self {
+ pub fn new_wrapped(child: crate::pipeline::Child<'a>) -> Self {
Self {
fut: Box::pin(async move { unreachable!() }),
wrapped_child: Some(Box::new(child)),
@@ -222,14 +227,24 @@ impl Child {
self.wrapped_child.as_ref().and_then(|cmd| cmd.id())
}
- #[async_recursion::async_recursion]
- pub async fn status(
+ // can't use async_recursion because it enforces a 'static lifetime
+ pub fn status(
self,
- ) -> anyhow::Result<async_std::process::ExitStatus> {
- if let Some(child) = self.wrapped_child {
- child.status().await
- } else {
- Ok(self.fut.await)
- }
+ ) -> std::pin::Pin<
+ Box<
+ dyn std::future::Future<
+ Output = anyhow::Result<async_std::process::ExitStatus>,
+ > + Send
+ + Sync
+ + 'a,
+ >,
+ > {
+ Box::pin(async move {
+ if let Some(child) = self.wrapped_child {
+ child.status().await
+ } else {
+ Ok(self.fut.await)
+ }
+ })
}
}