]>
Commit | Line | Data |
---|---|---|
ff7c6d11 XL |
1 | #![allow(dead_code)] |
2 | #![unstable(feature = "process_internals", issue = "0")] | |
3 | ||
532ac7d7 | 4 | use crate::collections::BTreeMap; |
e1599b0c XL |
5 | use crate::env; |
6 | use crate::ffi::{OsStr, OsString}; | |
7 | use crate::sys::process::EnvKey; | |
ff7c6d11 XL |
8 | |
9 | // Stores a set of changes to an environment | |
10 | #[derive(Clone, Debug)] | |
e1599b0c | 11 | pub struct CommandEnv { |
ff7c6d11 | 12 | clear: bool, |
0531ce1d | 13 | saw_path: bool, |
60c5eb7d | 14 | vars: BTreeMap<EnvKey, Option<OsString>>, |
ff7c6d11 XL |
15 | } |
16 | ||
e1599b0c | 17 | impl Default for CommandEnv { |
ff7c6d11 | 18 | fn default() -> Self { |
60c5eb7d | 19 | CommandEnv { clear: false, saw_path: false, vars: Default::default() } |
ff7c6d11 XL |
20 | } |
21 | } | |
22 | ||
e1599b0c | 23 | impl CommandEnv { |
ff7c6d11 | 24 | // Capture the current environment with these changes applied |
e1599b0c XL |
25 | pub fn capture(&self) -> BTreeMap<EnvKey, OsString> { |
26 | let mut result = BTreeMap::<EnvKey, OsString>::new(); | |
ff7c6d11 XL |
27 | if !self.clear { |
28 | for (k, v) in env::vars_os() { | |
29 | result.insert(k.into(), v); | |
30 | } | |
31 | } | |
32 | for (k, maybe_v) in &self.vars { | |
33 | if let &Some(ref v) = maybe_v { | |
34 | result.insert(k.clone(), v.clone()); | |
35 | } else { | |
36 | result.remove(k); | |
37 | } | |
38 | } | |
39 | result | |
40 | } | |
41 | ||
42 | // Apply these changes directly to the current environment | |
43 | pub fn apply(&self) { | |
44 | if self.clear { | |
45 | for (k, _) in env::vars_os() { | |
46 | env::remove_var(k); | |
47 | } | |
48 | } | |
49 | for (key, maybe_val) in self.vars.iter() { | |
50 | if let &Some(ref val) = maybe_val { | |
51 | env::set_var(key, val); | |
52 | } else { | |
53 | env::remove_var(key); | |
54 | } | |
55 | } | |
56 | } | |
57 | ||
58 | pub fn is_unchanged(&self) -> bool { | |
59 | !self.clear && self.vars.is_empty() | |
60 | } | |
61 | ||
e1599b0c | 62 | pub fn capture_if_changed(&self) -> Option<BTreeMap<EnvKey, OsString>> { |
60c5eb7d | 63 | if self.is_unchanged() { None } else { Some(self.capture()) } |
ff7c6d11 XL |
64 | } |
65 | ||
66 | // The following functions build up changes | |
67 | pub fn set(&mut self, key: &OsStr, value: &OsStr) { | |
0531ce1d | 68 | self.maybe_saw_path(&key); |
ff7c6d11 XL |
69 | self.vars.insert(key.to_owned().into(), Some(value.to_owned())); |
70 | } | |
e1599b0c | 71 | |
ff7c6d11 | 72 | pub fn remove(&mut self, key: &OsStr) { |
0531ce1d | 73 | self.maybe_saw_path(&key); |
ff7c6d11 XL |
74 | if self.clear { |
75 | self.vars.remove(key); | |
76 | } else { | |
77 | self.vars.insert(key.to_owned().into(), None); | |
78 | } | |
79 | } | |
e1599b0c | 80 | |
ff7c6d11 XL |
81 | pub fn clear(&mut self) { |
82 | self.clear = true; | |
83 | self.vars.clear(); | |
84 | } | |
e1599b0c | 85 | |
0531ce1d XL |
86 | pub fn have_changed_path(&self) -> bool { |
87 | self.saw_path || self.clear | |
88 | } | |
e1599b0c | 89 | |
0531ce1d XL |
90 | fn maybe_saw_path(&mut self, key: &OsStr) { |
91 | if !self.saw_path && key == "PATH" { | |
92 | self.saw_path = true; | |
93 | } | |
94 | } | |
ff7c6d11 | 95 | } |