use std::str::FromStr;
pub fn env_or_default<T: FromStr>(key: &str, default: T) -> T {
std::env::var(key)
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(default)
}
pub fn is_env_truthy(env: &str) -> bool {
is_env_set_and_truthy(env).unwrap_or_default()
}
pub fn is_env_set_and_truthy(env: &str) -> Option<bool> {
std::env::var(env)
.ok()
.map(|var| matches!(var.to_lowercase().as_str(), "1" | "true" | "yes" | "_yes_"))
}
#[macro_export]
macro_rules! def_is_env_truthy {
($fn_name:ident, $env: expr) => {
#[inline]
pub fn $fn_name() -> bool {
cfg_if::cfg_if! {
if #[cfg(test)] {
$crate::utils::misc::env::is_env_truthy($env)
} else{
static ENV: std::sync::LazyLock<bool> =
std::sync::LazyLock::new(|| $crate::utils::misc::env::is_env_truthy($env));
*ENV
}
}
}
};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_env_or_default() {
unsafe {
std::env::set_var("TEST_ENV", "42");
assert_eq!(env_or_default("TEST_ENV", 0), 42);
std::env::remove_var("TEST_ENV");
assert_eq!(env_or_default("TEST_ENV", 0), 0);
std::env::set_var("TEST_ENV", "42");
assert!(!env_or_default("TEST_ENV", false));
}
}
#[test]
fn test_is_env_truthy() {
let cases = [
("1", true),
("true", true),
("0", false),
("false", false),
("", false),
("cthulhu", false),
];
for (input, expected) in cases.iter() {
unsafe { std::env::set_var("TEST_ENV", input) };
assert_eq!(is_env_truthy("TEST_ENV"), *expected);
}
}
}