use std::sync::atomic::{AtomicUsize, Ordering};
pub const ALL: usize = 0;
pub const DEBUG: usize = 1;
pub const INFO: usize = 2;
pub const WARN: usize = 3;
pub const ERROR: usize = 4;
static LEVEL: AtomicUsize = AtomicUsize::new(3);
pub fn level() -> usize {
LEVEL.load(Ordering::SeqCst)
}
pub fn set_level(level: usize) {
LEVEL.store(level, Ordering::SeqCst)
}
#[doc(hidden)]
pub struct Logger<const LEVEL: usize>;
impl<const LEVEL: usize> std::fmt::Write for Logger<LEVEL> {
fn write_str(&mut self, s: &str) -> std::fmt::Result {
if LEVEL >= level() {
eprint!("{s}");
}
Ok(())
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! log {
($level:expr, $($arg:tt)*) => {
use std::fmt::Write;
let mut logger = $crate::log::Logger::<{ $level }>;
let _ = writeln!(&mut logger, $($arg)*);
};
}
#[macro_export]
macro_rules! log_debug {
($($arg:tt)*) => { $crate::log!($crate::log::DEBUG, $($arg)*) };
}
#[macro_export]
macro_rules! log_info {
($($arg:tt)*) => { $crate::log!($crate::log::INFO, $($arg)*) };
}
#[macro_export]
macro_rules! log_warn {
($($arg:tt)*) => { $crate::log!($crate::log::WARN, $($arg)*) };
}
#[macro_export]
macro_rules! log_error {
($($arg:tt)*) => { $crate::log!($crate::log::ERROR, $($arg)*) };
}