about summary refs log tree commit diff
path: root/library/std/src/sys_common
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-10-02 07:51:24 +0000
committerbors <bors@rust-lang.org>2020-10-02 07:51:24 +0000
commit154f1f544dd68f7b53ff8d9952811e855f4c2d7c (patch)
tree3c41537626d41a0dc9a89b1e8978cbb1535e9ff1 /library/std/src/sys_common
parentf283d3f02cf3ed261a519afe05cde9e23d1d9278 (diff)
parentc297e20e03452c659b6d3f026ce4beee42ed8738 (diff)
downloadrust-154f1f544dd68f7b53ff8d9952811e855f4c2d7c.tar.gz
rust-154f1f544dd68f7b53ff8d9952811e855f4c2d7c.zip
Auto merge of #77029 - ehuss:command-access, r=dtolnay
Add accessors to Command.

This adds some accessor methods to `Command` to provide a way to access the values set when building the `Command`. An example where this can be useful is to display the command to be executed. This is roughly based on the [`ProcessBuilder`](https://github.com/rust-lang/cargo/blob/13b73cdaf76b2d9182515c9cf26a8f68342d08ef/src/cargo/util/process_builder.rs#L105-L134) in Cargo.

Possible concerns about the API:
- Values with NULs on Unix will be returned as `"<string-with-nul>"`. I don't think it is practical to avoid this, since otherwise a whole separate copy of all the values would need to be kept in `Command`.
- Does not handle `arg0` on Unix. This can be awkward to support in `get_args` and is rarely used. I figure if someone really wants it, it can be added to `CommandExt` as a separate method.
- Does not offer a way to detect `env_clear`. I'm uncertain if it would be useful for anyone.
- Does not offer a way to get an environment variable by name (`get_env`). I figure this can be added later if anyone really wants it. I think the motivation for this is weak, though. Also, the API could be a little awkward (return a `Option<Option<&OsStr>>`?).
- `get_envs` could skip "cleared" entries and just return `&OsStr` values instead of `Option<&OsStr>`. I'm on the fence here. My use case is to display a shell command, and I only intend it to be roughly equivalent to the actual execution, and I probably won't display `None` entries. I erred on the side of providing extra information, but I suspect many situations will just filter out the `None`s.
- Could implement more iterator stuff (like `DoubleEndedIterator`).

I have not implemented new std items before, so I'm uncertain if the existing issue should be reused, or if a new tracking issue is needed.

cc #44434
Diffstat (limited to 'library/std/src/sys_common')
-rw-r--r--library/std/src/sys_common/process.rs37
1 files changed, 37 insertions, 0 deletions
diff --git a/library/std/src/sys_common/process.rs b/library/std/src/sys_common/process.rs
index f3a2962098b..fe89b11043c 100644
--- a/library/std/src/sys_common/process.rs
+++ b/library/std/src/sys_common/process.rs
@@ -92,4 +92,41 @@ impl CommandEnv {
             self.saw_path = true;
         }
     }
+
+    pub fn iter(&self) -> CommandEnvs<'_> {
+        let iter = self.vars.iter();
+        CommandEnvs { iter }
+    }
+}
+
+/// An iterator over the command environment variables.
+///
+/// This struct is created by
+/// [`Command::get_envs`][crate::process::Command::get_envs]. See its
+/// documentation for more.
+#[unstable(feature = "command_access", issue = "44434")]
+#[derive(Debug)]
+pub struct CommandEnvs<'a> {
+    iter: crate::collections::btree_map::Iter<'a, EnvKey, Option<OsString>>,
+}
+
+#[unstable(feature = "command_access", issue = "44434")]
+impl<'a> Iterator for CommandEnvs<'a> {
+    type Item = (&'a OsStr, Option<&'a OsStr>);
+    fn next(&mut self) -> Option<Self::Item> {
+        self.iter.next().map(|(key, value)| (key.as_ref(), value.as_deref()))
+    }
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.iter.size_hint()
+    }
+}
+
+#[unstable(feature = "command_access", issue = "44434")]
+impl<'a> ExactSizeIterator for CommandEnvs<'a> {
+    fn len(&self) -> usize {
+        self.iter.len()
+    }
+    fn is_empty(&self) -> bool {
+        self.iter.is_empty()
+    }
 }