use std::{
env::{remove_var, set_var, var_os},
ffi::{OsStr, OsString},
marker::PhantomData,
};
#[must_use]
pub struct VarGuard<T = OsString> {
key: &'static str,
value: Option<OsString>,
_phantom: PhantomData<T>,
}
impl<T: AsRef<OsStr>> VarGuard<T> {
pub fn set(key: &'static str, val: Option<T>) -> Self {
let value = var_os(key);
if let Some(val) = val {
unsafe { set_var(key, val) };
} else {
unsafe { remove_var(key) };
}
Self {
key,
value,
_phantom: PhantomData,
}
}
}
impl<T> Drop for VarGuard<T> {
fn drop(&mut self) {
match self.value.as_deref() {
None => unsafe { remove_var(self.key) },
Some(value) => unsafe { set_var(self.key, value) },
}
}
}