|
| 1 | +// smoelius: `VarGuard` is based on a struct of the same name from Clippy's source code. The `set` |
| 2 | +// method was modified to accept an `Option` so that variables could be cleared. Also, `unsafe` |
| 3 | +// annotations were added to make the struct compile with Rust Edition 2024. See: |
| 4 | +// https://github.com/rust-lang/rust-clippy/blob/c51472b4b09d22bdbb46027f08be54c4b285a725/tests/compile-test.rs#L267-L289 |
| 5 | + |
| 6 | +use std::{ |
| 7 | + env::{remove_var, set_var, var_os}, |
| 8 | + ffi::{OsStr, OsString}, |
| 9 | + marker::PhantomData, |
| 10 | +}; |
| 11 | + |
| 12 | +/// Restores an env var on drop |
| 13 | +#[must_use] |
| 14 | +pub struct VarGuard<T = OsString> { |
| 15 | + key: &'static str, |
| 16 | + value: Option<OsString>, |
| 17 | + _phantom: PhantomData<T>, |
| 18 | +} |
| 19 | + |
| 20 | +impl<T: AsRef<OsStr>> VarGuard<T> { |
| 21 | + pub fn set(key: &'static str, val: Option<T>) -> Self { |
| 22 | + let value = var_os(key); |
| 23 | + if let Some(val) = val { |
| 24 | + unsafe { set_var(key, val) }; |
| 25 | + } else { |
| 26 | + unsafe { remove_var(key) }; |
| 27 | + } |
| 28 | + Self { |
| 29 | + key, |
| 30 | + value, |
| 31 | + _phantom: PhantomData, |
| 32 | + } |
| 33 | + } |
| 34 | +} |
| 35 | + |
| 36 | +impl<T> Drop for VarGuard<T> { |
| 37 | + fn drop(&mut self) { |
| 38 | + match self.value.as_deref() { |
| 39 | + None => unsafe { remove_var(self.key) }, |
| 40 | + Some(value) => unsafe { set_var(self.key, value) }, |
| 41 | + } |
| 42 | + } |
| 43 | +} |
0 commit comments