use std::sync::Arc;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum LogLevel {
Debug,
Info,
Warn,
Error,
}
impl LogLevel {
fn label(self) -> &'static str {
match self {
LogLevel::Debug => "DEBUG",
LogLevel::Info => "INFO",
LogLevel::Warn => "WARN",
LogLevel::Error => "ERROR",
}
}
fn parse(s: &str) -> Option<LogLevel> {
match s.trim().to_ascii_lowercase().as_str() {
"debug" | "trace" => Some(LogLevel::Debug),
"info" => Some(LogLevel::Info),
"warn" | "warning" => Some(LogLevel::Warn),
"error" => Some(LogLevel::Error),
_ => None,
}
}
}
pub type Logger = Arc<dyn Fn(LogLevel, &str) + Send + Sync>;
pub const ENV_LOG: &str = "OBLODAI_LOG";
pub(crate) fn env_logger() -> Option<Logger> {
let raw = std::env::var(ENV_LOG).ok()?;
let min = LogLevel::parse(&raw)?;
let logger: Logger = Arc::new(move |level: LogLevel, msg: &str| {
if level >= min {
eprintln!("[oblodai {}] {}", level.label(), msg);
}
});
Some(logger)
}
pub(crate) fn log_env(level: LogLevel, msg: &str) {
if let Some(logger) = env_logger() {
logger(level, msg);
}
}