extern crate chrono;
extern crate env_logger;
extern crate log;
use anstyle::Color;
use chrono::Local;
use env_logger::{fmt::style::AnsiColor, Builder};
use log::LevelFilter;
use std::io::Write;
pub trait SetupLogging {
fn set_logging_level(self) -> LevelFilter;
fn enable_logging(&self);
}
fn set_builder(loglevel: LevelFilter) {
let _ = Builder::new()
.format(|buf, record| {
let time_style = anstyle::Style::new()
.fg_color(Some((159, 80, 1).into()))
.bold();
let level_style = match record.level() {
log::Level::Info => anstyle::Style::new()
.fg_color(Some(Color::from(AnsiColor::Green)))
.bold(),
log::Level::Debug => anstyle::Style::new()
.fg_color(Some(Color::from(AnsiColor::Cyan)))
.bold(),
log::Level::Trace => anstyle::Style::new()
.fg_color(Some(Color::from(AnsiColor::Magenta)))
.bold(),
log::Level::Error => anstyle::Style::new()
.fg_color(Some(Color::from(AnsiColor::Red)))
.bold(),
log::Level::Warn => anstyle::Style::new()
.fg_color(Some(Color::from(AnsiColor::Yellow)))
.bold(),
};
let level = format!("{level_style}{: <5}{level_style:#}", record.level());
let time = format!(
"{time_style}{}{time_style:#}",
Local::now().format("%Y-%m-%dT%H:%M:%S")
);
writeln!(buf, "[{}][{}]{}", level, time, record.args())
})
.filter(None, loglevel)
.try_init();
}
impl SetupLogging for &str {
fn set_logging_level(self) -> LevelFilter {
match self.to_lowercase().as_str() {
"error" => LevelFilter::Error,
"warn" => LevelFilter::Warn,
"info" => LevelFilter::Info,
"debug" => LevelFilter::Debug,
"trace" => LevelFilter::Trace,
_ => LevelFilter::Info,
}
}
fn enable_logging(&self) {
let loglevel = self.set_logging_level();
set_builder(loglevel);
}
}
impl SetupLogging for String {
fn set_logging_level(self) -> LevelFilter {
match self.to_lowercase().as_str() {
"error" => LevelFilter::Error,
"warn" => LevelFilter::Warn,
"info" => LevelFilter::Info,
"debug" => LevelFilter::Debug,
"trace" => LevelFilter::Trace,
_ => LevelFilter::Info,
}
}
fn enable_logging(&self) {
let loglevel = self.clone().set_logging_level();
set_builder(loglevel);
}
}
impl SetupLogging for usize {
fn set_logging_level(self) -> LevelFilter {
match self {
1 => LevelFilter::Error,
2 => LevelFilter::Warn,
3 => LevelFilter::Info,
4 => LevelFilter::Debug,
5 => LevelFilter::Trace,
_ => LevelFilter::Info,
}
}
fn enable_logging(&self) {
let loglevel = self.set_logging_level();
set_builder(loglevel);
}
}
impl SetupLogging for u8 {
fn set_logging_level(self) -> LevelFilter {
match self {
1 => LevelFilter::Error,
2 => LevelFilter::Warn,
3 => LevelFilter::Info,
4 => LevelFilter::Debug,
5 => LevelFilter::Trace,
_ => LevelFilter::Info,
}
}
fn enable_logging(&self) {
let loglevel = self.set_logging_level();
set_builder(loglevel);
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_set_logging_level() {
let info_level: u8 = 0;
let debug_level: u8 = 1;
let trace_level: u8 = 2;
let stupid_levels: u8 = 255;
let info_level_logging: LevelFilter = info_level.set_logging_level();
let debug_level_logging: LevelFilter = debug_level.set_logging_level();
let trace_level_logging: LevelFilter = trace_level.set_logging_level();
let stupid_levels_logging: LevelFilter = stupid_levels.set_logging_level();
assert_eq!(info_level_logging, LevelFilter::Info);
assert_eq!(debug_level_logging, LevelFilter::Debug);
assert_eq!(trace_level_logging, LevelFilter::Trace);
assert_eq!(stupid_levels_logging, LevelFilter::Trace);
}
}