1+ extern crate regex;
2+ use regex:: Regex ;
13use std:: ffi:: OsString ;
24
35/// Structure to deal with environment variables
@@ -7,13 +9,15 @@ pub struct Environment {
79 vars : Vec < ( OsString , OsString ) > ,
810 /// Define if the structure must inherit
911 inherit : bool ,
12+ save_pattern : Option < String > ,
1013}
1114
1215impl Default for Environment {
1316 fn default ( ) -> Self {
1417 Self {
1518 vars : vec ! [ ] ,
1619 inherit : false ,
20+ save_pattern : None ,
1721 }
1822 }
1923}
@@ -36,6 +40,7 @@ impl Environment {
3640 Self {
3741 vars : vec ! [ ] ,
3842 inherit : true ,
43+ save_pattern : None ,
3944 }
4045 }
4146
@@ -70,12 +75,49 @@ impl Environment {
7075 self
7176 }
7277
78+ /// Define a regex that will be used to save some existing variables.
79+ /// It's only used when having an inherit equal to false.
80+ ///
81+ /// # Examples
82+ ///
83+ /// ```rust
84+ /// extern crate environment;
85+ ///
86+ /// use std::ffi::OsString;
87+ ///
88+ /// ::std::env::set_var("BAR", "BAZ");
89+ ///
90+ /// let e = environment::Environment::empty().insert("foo", "bar").compile();
91+ ///
92+ /// assert_eq!(e, vec![(OsString::from("foo"), OsString::from("bar"))]);
93+ ///
94+ /// let e = environment::Environment::empty().save("BAR").insert("foo", "bar").compile();
95+ ///
96+ /// assert_eq!(e, vec![(OsString::from("BAR"), OsString::from("BAZ")), (OsString::from("foo"), OsString::from("bar"))]);
97+ /// ```
98+ pub fn save < S : Into < String > > ( mut self , pattern : S ) -> Self {
99+ self . save_pattern = Some ( pattern. into ( ) ) ;
100+
101+ self
102+ }
103+
73104 /// Compile Environment object
74105 pub fn compile ( self ) -> Vec < ( OsString , OsString ) > {
75106 if self . inherit {
76107 :: std:: env:: vars_os ( ) . chain ( self . vars ) . collect ( )
77108 } else {
78- self . vars
109+ match self . save_pattern {
110+ Some ( v) => {
111+ let re = Regex :: new ( & v) . unwrap ( ) ;
112+ :: std:: env:: vars_os ( )
113+ . filter ( |& ( ref k, _) |
114+ re. is_match ( k. to_str ( ) . unwrap ( ) )
115+ )
116+ . chain ( self . vars )
117+ . collect ( )
118+ } ,
119+ None => self . vars
120+ }
79121 }
80122 }
81123}
@@ -118,6 +160,7 @@ where
118160 Self {
119161 vars : v. into_iter ( ) . map ( |k| k. to_environment_tuple ( ) ) . collect ( ) ,
120162 inherit : false ,
163+ save_pattern : None ,
121164 }
122165 }
123166}
@@ -233,4 +276,21 @@ mod test {
233276 assert ! ( output. contains( "bar=vv" ) ) ;
234277 assert ! ( !output. contains( "bar=baz" ) ) ;
235278 }
279+
280+ #[ test]
281+ fn save_pattern ( ) {
282+ let e: Environment = vec ! [ ( "foo" , "bar" ) ] . into ( ) ;
283+
284+ let mut c = Command :: new ( "printenv" ) ;
285+
286+ let output = c. env_clear ( )
287+ . envs ( e. clone ( ) . save ( "PAT.*" ) . compile ( ) )
288+ . output ( )
289+ . expect ( "failed to execute command" ) ;
290+
291+ let output = String :: from_utf8_lossy ( & output. stdout ) ;
292+
293+ assert ! ( output. contains( "foo=bar" ) ) ;
294+ assert ! ( output. contains( "PATH" ) ) ;
295+ }
236296}
0 commit comments