2 #![unstable(feature = "process_internals", issue = "none")]
4 use crate::collections
::BTreeMap
;
6 use crate::ffi
::{OsStr, OsString}
;
7 use crate::sys
::process
::EnvKey
;
9 // Stores a set of changes to an environment
10 #[derive(Clone, Debug)]
11 pub struct CommandEnv
{
14 vars
: BTreeMap
<EnvKey
, Option
<OsString
>>,
17 impl Default
for CommandEnv
{
18 fn default() -> Self {
19 CommandEnv { clear: false, saw_path: false, vars: Default::default() }
24 // Capture the current environment with these changes applied
25 pub fn capture(&self) -> BTreeMap
<EnvKey
, OsString
> {
26 let mut result
= BTreeMap
::<EnvKey
, OsString
>::new();
28 for (k
, v
) in env
::vars_os() {
29 result
.insert(k
.into(), v
);
32 for (k
, maybe_v
) in &self.vars
{
33 if let &Some(ref v
) = maybe_v
{
34 result
.insert(k
.clone(), v
.clone());
42 // Apply these changes directly to the current environment
45 for (k
, _
) in env
::vars_os() {
49 for (key
, maybe_val
) in self.vars
.iter() {
50 if let Some(ref val
) = maybe_val
{
51 env
::set_var(key
, val
);
58 pub fn is_unchanged(&self) -> bool
{
59 !self.clear
&& self.vars
.is_empty()
62 pub fn capture_if_changed(&self) -> Option
<BTreeMap
<EnvKey
, OsString
>> {
63 if self.is_unchanged() { None }
else { Some(self.capture()) }
66 // The following functions build up changes
67 pub fn set(&mut self, key
: &OsStr
, value
: &OsStr
) {
68 let key
= EnvKey
::from(key
);
69 self.maybe_saw_path(&key
);
70 self.vars
.insert(key
, Some(value
.to_owned()));
73 pub fn remove(&mut self, key
: &OsStr
) {
74 let key
= EnvKey
::from(key
);
75 self.maybe_saw_path(&key
);
77 self.vars
.remove(&key
);
79 self.vars
.insert(key
, None
);
83 pub fn clear(&mut self) {
88 pub fn have_changed_path(&self) -> bool
{
89 self.saw_path
|| self.clear
92 fn maybe_saw_path(&mut self, key
: &EnvKey
) {
93 if !self.saw_path
&& key
== "PATH" {
98 pub fn iter(&self) -> CommandEnvs
<'_
> {
99 let iter
= self.vars
.iter();
104 /// An iterator over the command environment variables.
106 /// This struct is created by
107 /// [`Command::get_envs`][crate::process::Command::get_envs]. See its
108 /// documentation for more.
109 #[must_use = "iterators are lazy and do nothing unless consumed"]
110 #[stable(feature = "command_access", since = "1.57.0")]
112 pub struct CommandEnvs
<'a
> {
113 iter
: crate::collections
::btree_map
::Iter
<'a
, EnvKey
, Option
<OsString
>>,
116 #[stable(feature = "command_access", since = "1.57.0")]
117 impl<'a
> Iterator
for CommandEnvs
<'a
> {
118 type Item
= (&'a OsStr
, Option
<&'a OsStr
>);
119 fn next(&mut self) -> Option
<Self::Item
> {
120 self.iter
.next().map(|(key
, value
)| (key
.as_ref(), value
.as_deref()))
122 fn size_hint(&self) -> (usize, Option
<usize>) {
123 self.iter
.size_hint()
127 #[stable(feature = "command_access", since = "1.57.0")]
128 impl<'a
> ExactSizeIterator
for CommandEnvs
<'a
> {
129 fn len(&self) -> usize {
132 fn is_empty(&self) -> bool
{