const SCOPED_PREFIXES: [&str; 4] = ["AWS_", "GOOGLE_", "AZURE_", "EARTHSCI_S3_"];
static ENV_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
pub(crate) struct EnvScope {
_guard: std::sync::MutexGuard<'static, ()>,
restore: Vec<(String, String)>,
clear: Vec<String>,
}
impl EnvScope {
pub(crate) fn new(vars: &[(&str, &str)]) -> Self {
let guard = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
let restore: Vec<(String, String)> = std::env::vars()
.filter(|(k, _)| SCOPED_PREFIXES.iter().any(|p| k.starts_with(p)))
.collect();
for (k, _) in &restore {
std::env::remove_var(k);
}
for (k, v) in vars {
std::env::set_var(k, v);
}
Self {
_guard: guard,
restore,
clear: vars.iter().map(|(k, _)| (*k).to_string()).collect(),
}
}
}
impl Drop for EnvScope {
fn drop(&mut self) {
for k in &self.clear {
std::env::remove_var(k);
}
for (k, v) in &self.restore {
std::env::set_var(k, v);
}
}
}