#![deny(clippy::unwrap_used)]
#![cfg(feature = "bin")]
use std::{
env,
io::{Write, stdout},
};
use colored::{Colorize, control::set_override};
use log::{Level, LevelFilter, Log, Metadata, Record};
#[derive(Default)]
struct SimpleLogger;
impl SimpleLogger {
fn level_color(level: &Level) -> String {
let name = format!("{:>5}", level.as_str().to_uppercase());
match level {
Level::Error => name.red().bold().to_string(),
Level::Warn => name.yellow().bold().to_string(),
Level::Info => name.green().bold().to_string(),
Level::Debug => name.blue().bold().to_string(),
Level::Trace => name.magenta().bold().to_string(),
}
}
}
impl Log for SimpleLogger {
fn enabled(&self, metadata: &Metadata) -> bool {
metadata.level() <= log::max_level()
}
fn log(&self, record: &Record) {
let mut stdout = stdout().lock();
if record.target() == "CI_LOG_GROUPING" {
writeln!(stdout, "{}", record.args()).expect("Failed to write log command to stdout");
stdout
.flush()
.expect("Failed to flush log command in stdout");
} else if self.enabled(record.metadata()) {
let module = record.module_path();
if module.is_none_or(|v| v.starts_with("cpp_linter")) {
writeln!(
stdout,
"[{}]: {}",
Self::level_color(&record.level()),
record.args()
)
.expect("Failed to write log message to stdout");
} else if let Some(module) = module {
writeln!(
stdout,
"[{}]{{{}:{}}}: {}",
Self::level_color(&record.level()),
module,
record.line().unwrap_or_default(),
record.args()
)
.expect("Failed to write detailed log message to stdout");
}
stdout
.flush()
.expect("Failed to flush log message in stdout");
}
}
fn flush(&self) {}
}
pub fn try_init() {
let logger: SimpleLogger = SimpleLogger;
if matches!(
env::var("CPP_LINTER_COLOR").as_deref(),
Ok("on" | "1" | "true")
) {
set_override(true);
}
if let Err(e) =
log::set_boxed_logger(Box::new(logger)).map(|()| log::set_max_level(LevelFilter::Info))
{
log::debug!("{e:?}");
}
}
#[cfg(test)]
mod test {
use std::env;
use super::{SimpleLogger, try_init};
#[test]
fn trace_log() {
unsafe {
env::set_var("CPP_LINTER_COLOR", "true");
}
try_init();
assert!(SimpleLogger::level_color(&log::Level::Trace).contains("TRACE"));
log::set_max_level(log::LevelFilter::Trace);
log::trace!("A dummy log statement for code coverage");
}
}