struct Logger {
to: Option<Box<dyn std::io::Write>>,
}
static mut LOGGER: Logger = Logger { to: None };
#[derive(PartialEq, PartialOrd, Copy, Clone)]
pub enum Level {
Trace,
Debug,
Info,
Warn,
Error,
}
static mut LEVEL: Level = Level::Info;
impl Logger {
pub fn log(&mut self, args: std::fmt::Arguments<'_>) {
if let Some(ref mut to) = self.to {
let _ = to.write_fmt(args).unwrap();
}
}
}
pub fn init(to: impl std::io::Write + 'static, level: Level) {
unsafe {
LOGGER = Logger {
to: Some(Box::new(to)),
};
LEVEL = level;
}
}
pub fn with_file(name: &str) {
unsafe {
LOGGER = Logger {
to: Some(Box::new(
std::fs::File::options()
.create(true)
.append(true)
.open(name.to_string())
.unwrap(),
)),
};
}
}
#[inline]
pub fn set_level(level: Level) {
unsafe {
LEVEL = level;
}
}
#[inline]
pub fn level() -> Level {
unsafe { LEVEL }
}
#[inline]
pub fn log(args: std::fmt::Arguments<'_>) {
unsafe {
LOGGER.log(args);
}
}
#[macro_export]
macro_rules! log_dispatch {
($lv:literal $level:ident opt,$val:expr,$($tail:tt)*) => {
{
let mut temp = $val;
if $crate::log::level() <= $crate::log::Level::$level && temp.is_none() {
$crate::log::log(format_args!("[{}][OPT] {}\n",$lv,format_args!($($tail)*)));
}
temp
}
};
($lv:literal $level:ident res,$val:expr,$($tail:tt)*) => {
($val).map_err(|e|{
if $crate::log::level() <= $crate::log::Level::$level{
$crate::log::log(format_args!("[{}][RES] {} [E]:{}\n",$lv,format_args!($($tail)*),e));
}
e
})
};
($lv:literal $level:ident $($tail:tt)*) => {
if $crate::log::level() <= $crate::log::Level::$level{
$crate::log::log(format_args!("[{}] {}\n",$lv,format_args!($($tail)*)));
}
}
}
#[macro_export]
macro_rules! trace {
($($tail:tt)*) => {
$crate::log_dispatch!("TRACE" Trace $($tail)*);
};
}
#[macro_export]
macro_rules! debug {
($($tail:tt)*) => {
$crate::log_dispatch!("DEBUG" Debug $($tail)*);
};
}
#[macro_export]
macro_rules! info {
($($tail:tt)*) => {
$crate::log_dispatch!("INFO" Info $($tail)*);
};
}
#[macro_export]
macro_rules! warn {
($($tail:tt)*) => {
$crate::log_dispatch!("WARN" Warn $($tail)*);
};
}
#[macro_export]
macro_rules! error {
($($tail:tt)*) => {
$crate::log_dispatch!("ERROR" Error $($tail)*);
};
}