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,53 @@ 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!(
97+ /// e,
98+ /// vec![
99+ /// (OsString::from("BAR"), OsString::from("BAZ")),
100+ /// (OsString::from("foo"), OsString::from("bar"))
101+ /// ]
102+ /// );
103+ /// ```
104+ pub fn save < S : Into < String > > ( mut self , pattern : S ) -> Self {
105+ self . save_pattern = Some ( pattern. into ( ) ) ;
106+
107+ self
108+ }
109+
73110 /// Compile Environment object
74111 pub fn compile ( self ) -> Vec < ( OsString , OsString ) > {
75112 if self . inherit {
76113 :: std:: env:: vars_os ( ) . chain ( self . vars ) . collect ( )
77114 } else {
78- self . vars
115+ match self . save_pattern {
116+ Some ( v) => {
117+ let re = Regex :: new ( & v) . unwrap ( ) ;
118+ :: std:: env:: vars_os ( )
119+ . filter ( |& ( ref k, _) | re. is_match ( k. to_str ( ) . unwrap ( ) ) )
120+ . chain ( self . vars )
121+ . collect ( )
122+ }
123+ None => self . vars
124+ }
79125 }
80126 }
81127}
@@ -118,6 +164,7 @@ where
118164 Self {
119165 vars : v. into_iter ( ) . map ( |k| k. to_environment_tuple ( ) ) . collect ( ) ,
120166 inherit : false ,
167+ save_pattern : None ,
121168 }
122169 }
123170}
@@ -233,4 +280,21 @@ mod test {
233280 assert ! ( output. contains( "bar=vv" ) ) ;
234281 assert ! ( !output. contains( "bar=baz" ) ) ;
235282 }
283+
284+ #[ test]
285+ fn save_pattern ( ) {
286+ let e: Environment = vec ! [ ( "foo" , "bar" ) ] . into ( ) ;
287+
288+ let mut c = Command :: new ( "printenv" ) ;
289+
290+ let output = c. env_clear ( )
291+ . envs ( e. clone ( ) . save ( "PAT.*" ) . compile ( ) )
292+ . output ( )
293+ . expect ( "failed to execute command" ) ;
294+
295+ let output = String :: from_utf8_lossy ( & output. stdout ) ;
296+
297+ assert ! ( output. contains( "foo=bar" ) ) ;
298+ assert ! ( output. contains( "PATH" ) ) ;
299+ }
236300}
0 commit comments