use colored::{ColoredString, Colorize};
use crate::internal;
use crate::level;
pub struct LogLevel {
name : String,
severity : u32,
formatter : Box<dyn Fn(String) -> ColoredString>,
init : bool
}
impl LogLevel {
pub fn new(severity : u32) -> LogLevel {
let level = LogLevel {
name : String::new(),
severity,
formatter : Box::new(|v| v.normal()),
init : false
};
return level;
}
pub fn init(mut self, name : &str) -> LogLevel {
if (self.init) {
panic!("`init` already called.");
}
self.init = true;
self.name = String::from(name);
if (unsafe {internal::MAX_LEVEL_NAME_LEN} < self.name.len()) {
unsafe {
internal::MAX_LEVEL_NAME_LEN = self.name.len();
}
}
return self;
}
pub fn formatted<F : 'static>(mut self, formatter : F) -> LogLevel
where F : Fn(String) -> ColoredString
{
self.formatter = Box::new(formatter);
return self;
}
}
impl LogLevel {
pub fn get_name(&self) -> String {
return String::from(&self.name);
}
pub fn get_severity(&self) -> u32 {
return self.severity;
}
pub fn format(&self, text : String) -> String {
return (self.formatter)(text).to_string();
}
}
unsafe impl Sync for LogLevel {}
#[macro_export]
macro_rules! log_level {
($name:ident, $level:expr) => {
#[allow(non_snake_case)]
pub mod $name {
use super::*;
extern crate static_init;
#[static_init::dynamic]
pub static LEVEL : $crate::level::LogLevel = $level.init(stringify!($name));
pub fn SEVERITY() -> u32 {
return LEVEL.get_severity();
}
}
};
}
pub(crate) use log_level;
log_level!(TRACE, level::LogLevel::new(5)
.formatted(|v| v.bright_black())
);
log_level!(DEBUG, level::LogLevel::new(10)
.formatted(|v| v.white().dimmed())
);
log_level!(INFO, level::LogLevel::new(20)
.formatted(|v| v.cyan().dimmed())
);
log_level!(NOTICE, level::LogLevel::new(25)
.formatted(|v| v.bright_cyan())
);
log_level!(SUCCESS, level::LogLevel::new(25)
.formatted(|v| v.green())
);
log_level!(WARN, level::LogLevel::new(30)
.formatted(|v| v.yellow())
);
log_level!(FAILURE, level::LogLevel::new(35)
.formatted(|v| v.red())
);
log_level!(ERROR, level::LogLevel::new(40)
.formatted(|v| v.bright_red().bold())
);
log_level!(FATAL, level::LogLevel::new(50)
.formatted(|v| v.bright_white().bold().on_red())
);