use crate::enums::log_level::LogLevel;
use crate::structs::logger::Logger;
use std::io;
use std::sync::{OnceLock, RwLock};
static GLOBAL_LOGGER: OnceLock<RwLock<Logger>> = OnceLock::new();
fn init_global_logger() -> &'static RwLock<Logger> {
GLOBAL_LOGGER.get_or_init(|| RwLock::new(Logger::from_env()))
}
pub fn get_global_logger() -> &'static RwLock<Logger> {
init_global_logger()
}
pub fn get_global_mut() -> std::sync::RwLockWriteGuard<'static, Logger> {
GLOBAL_LOGGER
.get_or_init(|| RwLock::new(Logger::from_env()))
.write()
.unwrap()
}
pub fn error(message: &str) -> io::Result<()> {
get_global_logger().read().unwrap().error(message)
}
pub fn warning(message: &str) -> io::Result<()> {
get_global_logger().read().unwrap().warning(message)
}
pub fn info(message: &str) -> io::Result<()> {
get_global_logger().read().unwrap().info(message)
}
pub fn debug(message: &str) -> io::Result<()> {
get_global_logger().read().unwrap().debug(message)
}
pub fn trace(message: &str) -> io::Result<()> {
get_global_logger().read().unwrap().trace(message)
}
pub fn log(message: &str) -> io::Result<()> {
get_global_logger().read().unwrap().log(message)
}
pub fn log_with_level(level: LogLevel, message: &str) -> io::Result<()> {
get_global_logger().read().unwrap().log_with_level(level, message)
}
pub fn error_lazy<F>(message_fn: F) -> io::Result<()>
where
F: FnOnce() -> String,
{
get_global_logger().read().unwrap().error_lazy(message_fn)
}
pub fn warning_lazy<F>(message_fn: F) -> io::Result<()>
where
F: FnOnce() -> String,
{
get_global_logger().read().unwrap().warning_lazy(message_fn)
}
pub fn info_lazy<F>(message_fn: F) -> io::Result<()>
where
F: FnOnce() -> String,
{
get_global_logger().read().unwrap().info_lazy(message_fn)
}
pub fn debug_lazy<F>(message_fn: F) -> io::Result<()>
where
F: FnOnce() -> String,
{
get_global_logger().read().unwrap().debug_lazy(message_fn)
}
pub fn trace_lazy<F>(message_fn: F) -> io::Result<()>
where
F: FnOnce() -> String,
{
get_global_logger().read().unwrap().trace_lazy(message_fn)
}
pub fn log_lazy<F>(message_fn: F) -> io::Result<()>
where
F: FnOnce() -> String,
{
get_global_logger()
.read()
.unwrap()
.log_lazy(message_fn)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_convenience_functions() -> io::Result<()> {
error("Test error")?;
warning("Test warning")?;
info("Test info")?;
debug("Test debug")?;
trace("Test trace")?;
let global_logger = get_global_logger();
let logger = global_logger.read().unwrap();
assert_eq!(logger.level(), LogLevel::Info);
Ok(())
}
#[test]
fn test_lazy_convenience_functions() -> io::Result<()> {
let mut called = false;
debug_lazy(|| {
called = true;
"Debug message".to_string()
})?;
called = false;
info_lazy(|| {
called = true;
"Info message".to_string()
})?;
assert!(
called,
"Lazy closure should have been called for info level"
);
Ok(())
}
}