use std::collections::HashMap;
use static_init::dynamic;
use crate::Logger;
pub enum LoggerLocation {
Super,
Here(Logger)
}
unsafe impl Send for LoggerLocation {}
#[dynamic]
pub static mut LOGGERS : HashMap<String, LoggerLocation> = {
let mut map = HashMap::new();
map.insert(String::new(), LoggerLocation::Here(Logger::default()));
map
};
pub static mut MAX_LEVEL_NAME_LEN : usize = 0;
pub static mut MAX_MODULE_LEN : usize = 0;
pub fn run_module_logger<F>(module : String, first : bool, callback : F)
where F : Fn(&Logger)
{
let mut next_module_vec = module.split("::").collect::<Vec<&str>>();
next_module_vec.remove(next_module_vec.len() - 1);
let next_module = next_module_vec.join("::");
match (LOGGERS.read().get(&module)) {
Some(location) => {
match (location) {
LoggerLocation::Super => {
run_module_logger(next_module, false, callback);
},
LoggerLocation::Here(logger) => {
callback(&logger);
}
}
},
None => {
if (first) {
panic!("Logger for module `{}` not registered.", module);
} else {
run_module_logger(next_module, false, callback);
}
}
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! __logger_internal {
($location:expr) => {
#[allow(non_snake_case)]
mod __loggerithm_LOGGER {
extern crate static_init;
#[static_init::dynamic]
static LOGGER : () = {
let mut module_vec = module_path!().split("::").collect::<Vec<&str>>();
module_vec.remove(module_vec.len() - 1);
let module = module_vec.join("::");
if (unsafe {$crate::internal::MAX_MODULE_LEN} < module.len()) {
unsafe {
$crate::internal::MAX_MODULE_LEN = module.len();
}
}
unsafe {$crate::internal::LOGGERS.write()}
.insert(module, $location);
};
#[allow(dead_code)]
pub fn void() {}
}
};
}