use std::sync::atomic::{AtomicI8, Ordering};
#[inline]
pub(crate) fn env_default_true(name: &str) -> bool {
match std::env::var(name).ok().as_deref() {
None => true,
Some(v)
if v.eq_ignore_ascii_case("0")
|| v.eq_ignore_ascii_case("false")
|| v.eq_ignore_ascii_case("off") =>
{
false
}
Some(_) => true,
}
}
#[inline]
pub(crate) fn cached_env_default_true(cache: &AtomicI8, name: &str) -> bool {
let v = cache.load(Ordering::Relaxed);
if v >= 0 {
return v == 1;
}
let on = env_default_true(name);
cache.store(if on { 1 } else { 0 }, Ordering::Relaxed);
on
}
#[inline]
pub(crate) fn cached_env_eq_one(cache: &AtomicI8, name: &str) -> bool {
let v = cache.load(Ordering::Relaxed);
if v >= 0 {
return v == 1;
}
let on = std::env::var(name).ok().as_deref() == Some("1");
cache.store(if on { 1 } else { 0 }, Ordering::Relaxed);
on
}
#[cfg(test)]
mod tests {
use super::env_default_true;
use std::sync::Mutex;
static ENV_LOCK: Mutex<()> = Mutex::new(());
fn with_env<F: FnOnce()>(name: &str, value: Option<&str>, body: F) {
let _g = ENV_LOCK.lock().expect("env lock poisoned");
let prev = std::env::var(name).ok();
match value {
Some(v) => std::env::set_var(name, v),
None => std::env::remove_var(name),
}
body();
match prev {
Some(v) => std::env::set_var(name, v),
None => std::env::remove_var(name),
}
}
#[test]
fn unset_returns_true() {
with_env("MLX_NATIVE_TEST_DEFAULT_TRUE_A", None, || {
assert!(env_default_true("MLX_NATIVE_TEST_DEFAULT_TRUE_A"));
});
}
#[test]
fn explicit_one_returns_true() {
with_env("MLX_NATIVE_TEST_DEFAULT_TRUE_B", Some("1"), || {
assert!(env_default_true("MLX_NATIVE_TEST_DEFAULT_TRUE_B"));
});
}
#[test]
fn explicit_zero_returns_false() {
with_env("MLX_NATIVE_TEST_DEFAULT_TRUE_C", Some("0"), || {
assert!(!env_default_true("MLX_NATIVE_TEST_DEFAULT_TRUE_C"));
});
}
#[test]
fn explicit_false_returns_false() {
with_env("MLX_NATIVE_TEST_DEFAULT_TRUE_D", Some("false"), || {
assert!(!env_default_true("MLX_NATIVE_TEST_DEFAULT_TRUE_D"));
});
with_env("MLX_NATIVE_TEST_DEFAULT_TRUE_D", Some("FALSE"), || {
assert!(!env_default_true("MLX_NATIVE_TEST_DEFAULT_TRUE_D"));
});
}
#[test]
fn explicit_off_returns_false() {
with_env("MLX_NATIVE_TEST_DEFAULT_TRUE_E", Some("off"), || {
assert!(!env_default_true("MLX_NATIVE_TEST_DEFAULT_TRUE_E"));
});
with_env("MLX_NATIVE_TEST_DEFAULT_TRUE_E", Some("OFF"), || {
assert!(!env_default_true("MLX_NATIVE_TEST_DEFAULT_TRUE_E"));
});
}
#[test]
fn unrecognized_returns_true_permissive() {
with_env("MLX_NATIVE_TEST_DEFAULT_TRUE_F", Some("yes"), || {
assert!(env_default_true("MLX_NATIVE_TEST_DEFAULT_TRUE_F"));
});
with_env("MLX_NATIVE_TEST_DEFAULT_TRUE_F", Some("enable"), || {
assert!(env_default_true("MLX_NATIVE_TEST_DEFAULT_TRUE_F"));
});
}
}