env_test_util/lib.rs
1/// Temporary environment variable manager
2///
3/// When initialising the variable manager with `new`, the actual content will be removed and stored
4/// in `initial_value`. You can then set a temporary value using the method `with`. The environment
5/// variable will then be reset to it's initial value when it will be dropped.
6///
7/// # Examples
8///
9/// ```
10/// use env_test_util::TempEnvVar;
11///
12/// std::env::set_var("MY_VARIABLE", "ORIGINAL"); // set the variable to "ORIGINAL"
13/// let variable = TempEnvVar::new("MY_VARIABLE"); // read the variable and stores it
14/// assert_eq!(std::env::var("MY_VARIABLE").ok(), None);
15/// let variable = variable.with("NEW_CONTENT"); // set the environment variable with a new content
16/// assert_eq!(std::env::var("MY_VARIABLE").ok(), Some("NEW_CONTENT".into()));
17/// drop(variable);
18/// assert_eq!(std::env::var("MY_VARIABLE").ok(), Some("ORIGINAL".into()));
19/// ```
20///
21/// Don't forget to assign the variable in your tests, otherwise the `drop` function will be called right away
22///
23/// ```
24/// use env_test_util::TempEnvVar;
25///
26/// std::env::set_var("MY_VARIABLE", "ORIGINAL"); // set the variable to "ORIGINAL"
27/// TempEnvVar::new("MY_VARIABLE").with("SOMETHING_ELSE"); // read the variable and stores it
28/// assert_eq!(std::env::var("MY_VARIABLE").ok(), Some("ORIGINAL".into()));
29/// let _variable = TempEnvVar::new("MY_VARIABLE").with("SOMETHING_ELSE"); // Instead, store it in a variable
30/// assert_eq!(std::env::var("MY_VARIABLE").ok(), Some("SOMETHING_ELSE".into()));
31/// ```
32pub struct TempEnvVar {
33 /// name of the environment variable
34 pub key: String,
35 /// initial value of the environment variable
36 pub initial_value: Option<String>,
37}
38
39impl TempEnvVar {
40 /// creates a new temporary environment variable manager
41 pub fn new(key: &str) -> Self {
42 let initial_value = std::env::var(key).ok();
43 std::env::remove_var(key);
44 Self {
45 key: key.into(),
46 initial_value,
47 }
48 }
49
50 /// set the environment with a new temporary value
51 pub fn with(self, value: &str) -> Self {
52 std::env::set_var(self.key.as_str(), value);
53 self
54 }
55}
56
57impl Drop for TempEnvVar {
58 fn drop(&mut self) {
59 match self.initial_value.as_ref() {
60 Some(value) => std::env::set_var(self.key.as_str(), value),
61 None => std::env::remove_var(self.key.as_str()),
62 }
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
71 fn with_non_existing_variable() {
72 let name = "MISSINGVAR";
73 std::env::remove_var(name);
74 let variable = TempEnvVar::new(name);
75 assert_eq!(variable.initial_value, None);
76 assert_eq!(std::env::var(name).ok(), None);
77 let variable = variable.with("SOMETHING");
78 assert_eq!(variable.initial_value, None);
79 assert_eq!(std::env::var(name).ok(), Some("SOMETHING".into()));
80 drop(variable);
81 assert_eq!(std::env::var(name).ok(), None);
82 }
83
84 #[test]
85 fn with_existing_variable() {
86 let name = "EXISTINGVAR";
87 std::env::set_var(name, "INITIAL");
88 let variable = TempEnvVar::new(name);
89 assert_eq!(variable.initial_value, Some("INITIAL".into()));
90 assert_eq!(std::env::var(name).ok(), None);
91 let variable = variable.with("SOMETHING");
92 assert_eq!(variable.initial_value, Some("INITIAL".into()));
93 assert_eq!(std::env::var(name).ok(), Some("SOMETHING".into()));
94 drop(variable);
95 assert_eq!(std::env::var(name).ok(), Some("INITIAL".into()));
96 }
97}