You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

137 lines
2.4 KiB

mod color;
mod conf;
mod level;
mod standard;
pub use self::{color::Color, conf::Conf, level::Level, standard::Std};
use std::collections::HashMap;
#[macro_export]
macro_rules! lg {
($to:expr, $level:expr, $($args:tt)+) => {
match ($level, $to) {
(level, to) => {
if to.enabled(level) {
let record = $crate::log::Record {
level,
module: std::module_path!(),
file: std::file!(),
line: std::line!(),
column: std::column!(),
};
to.log(std::format_args!($($args)+), record);
}
}
}
};
}
#[macro_export]
macro_rules! trace {
($to:expr) => {
{
#[cfg(debug_assertions)]
$crate::lg!($to, $crate::log::Level::Trace, "");
}
};
($to:expr, $val:expr) => {
match $val {
val => {
#[cfg(debug_assertions)]
$crate::lg!(
$to,
$crate::log::Level::Trace,
"{} = {:#?}",
std::stringify!($val),
&val,
);
val
}
}
};
($to:expr, $($val:expr),+ $(,)?) => {
($($crate::trace!($to, $val)),+,)
};
}
pub struct Record {
pub level: Level,
pub module: &'static str,
pub file: &'static str,
pub line: u32,
pub column: u32,
}
pub struct Log {
level: Level,
begin: std::time::Instant,
modes: HashMap<&'static str, Box<dyn Mode>>,
mode: &'static str,
}
pub trait Mode {
fn log(&self, args: std::fmt::Arguments, record: Record, log: &Log);
}
impl Default for Log {
fn default() -> Self {
let mut modes: HashMap<_, Box<dyn Mode>> = HashMap::new();
modes.insert("Std", Box::new(Std));
Self {
modes,
level: Level::default(),
begin: std::time::Instant::now(),
mode: "Std",
}
}
}
impl Log {
pub fn enabled(&self, level: Level) -> bool {
level <= self.level
}
pub fn insert_mode<M>(mut self, name: &'static str, mode: M) -> Self
where
M: Mode + 'static,
{
self.modes.insert(name, Box::new(mode));
self
}
pub fn set_mode(mut self, name: &'static str) -> Result<Self, ()> {
if self.modes.contains_key(name) {
self.mode = name;
Ok(self)
} else {
Err(())
}
}
pub fn log(&self, args: std::fmt::Arguments, record: Record) {
self.modes[self.mode].log(args, record, self);
}
pub fn write_into(
&self, args: std::fmt::Arguments, record: Record,
out: &mut impl std::io::Write,
) -> std::io::Result<()> {
writeln!(
out,
"[{}:{}:{}:{}][{}ms] {}",
record.file,
record.line,
record.column,
record.module,
self.begin.elapsed().as_millis(),
args,
)?;
Ok(())
}
}
// EOF