nushell/crates/nu-test-support/src/locale_override.rs
Jaffar Ashoor c3c41a61b0
replace lazy_static with once_cell (#7502)
replacing the dependence on `lazy_static` with `once_cell`, this will
ensure that variables are initialized when needed instead of startup
time.
2022-12-17 10:30:04 -08:00

45 lines
1.4 KiB
Rust

#![cfg(debug_assertions)]
use std::sync::{Arc, Mutex};
use nu_utils::locale::LOCALE_OVERRIDE_ENV_VAR;
use once_cell::sync::Lazy;
static LOCALE_OVERRIDE_MUTEX: Lazy<Arc<Mutex<()>>> = Lazy::new(Default::default);
/// Run a closure in a fake locale environment.
///
/// Before the closure is executed, an environment variable whose name is
/// defined in `nu_utils::locale::LOCALE_OVERRIDE_ENV_VAR` is set to the value
/// provided by `locale_string`. When the closure is done, the previous value is
/// restored.
///
/// Environment variables are global values. So when they are changed by one
/// thread they are changed for all others. To prevent a test from overwriting
/// the environment variable of another test, a mutex is used.
pub fn with_locale_override<T>(locale_string: &str, func: fn() -> T) -> T {
let result = {
let _lock = LOCALE_OVERRIDE_MUTEX
.lock()
.expect("Failed to get mutex lock for locale override");
let saved = std::env::var(LOCALE_OVERRIDE_ENV_VAR).ok();
std::env::set_var(LOCALE_OVERRIDE_ENV_VAR, locale_string);
let result = std::panic::catch_unwind(func);
if let Some(locale_str) = saved {
std::env::set_var(LOCALE_OVERRIDE_ENV_VAR, locale_str);
} else {
std::env::remove_var(LOCALE_OVERRIDE_ENV_VAR);
}
result
};
match result {
Ok(result) => result,
Err(err) => std::panic::resume_unwind(err),
}
}