use crate::{
format::{Formatter, Record},
Level,
};
use cirious_codex_term::{Color, StyleExt};
#[must_use]
pub const fn level_color(level: Level) -> Color {
match level {
Level::Error => Color::Red,
Level::Warn => Color::Yellow,
Level::Info => Color::Blue,
Level::Debug => Color::Magenta,
Level::Trace => Color::BrightBlack,
}
}
#[derive(Debug, Default)]
pub struct StyledTerminalFormatter;
impl Formatter for StyledTerminalFormatter {
fn format(&self, record: &Record) -> String {
let level_tag = format!("{:?}", record.level).to_uppercase();
let styled_level = format!("[{level_tag}]").bold().color(level_color(record.level));
let timestamp = format!("[{}]", format_timestamp(record.timestamp))
.rgb(68, 68, 68)
.bold();
let base = format!("{timestamp} {styled_level}");
if record.level == Level::Trace {
let trace_loc = format!("[{}:{}:{}]", record.file, record.module_path, record.line)
.bold()
.bright_black();
format!("{} {} {}", base, trace_loc, record.args)
} else {
format!("{} {}", base, record.args)
}
}
}
fn format_timestamp(time: std::time::SystemTime) -> String {
use std::time::UNIX_EPOCH;
let duration = time.duration_since(UNIX_EPOCH).unwrap_or_default();
let secs = duration.as_secs();
format!("{:02}:{:02}:{:02}", (secs / 3600) % 24, (secs / 60) % 60, secs % 60)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Level;
use std::time::SystemTime;
#[test]
fn test_level_color_mapping() {
assert_eq!(level_color(Level::Error), Color::Red);
assert_eq!(level_color(Level::Warn), Color::Yellow);
assert_eq!(level_color(Level::Info), Color::Blue);
assert_eq!(level_color(Level::Debug), Color::Magenta);
assert_eq!(level_color(Level::Trace), Color::BrightBlack);
}
#[test]
fn test_format_timestamp() {
let time = SystemTime::UNIX_EPOCH;
assert_eq!(format_timestamp(time), "00:00:00");
}
#[test]
fn test_styled_terminal_formatter_output() {
let formatter = StyledTerminalFormatter;
let record = Record {
level: Level::Info,
args: "Operação iniciada".to_string(),
file: "main.rs",
line: 10,
module_path: "app::core",
timestamp: SystemTime::UNIX_EPOCH,
};
let result = formatter.format(&record);
assert!(result.contains("INFO")); assert!(result.contains("Operação iniciada")); assert!(result.contains("00:00:00")); }
#[test]
fn test_styled_terminal_formatter_trace_layout() {
let formatter = StyledTerminalFormatter;
let record = Record {
level: Level::Trace,
args: "Loop executando".to_string(),
file: "loop.rs",
line: 55,
module_path: "app::util",
timestamp: SystemTime::UNIX_EPOCH,
};
let result = formatter.format(&record);
assert!(result.contains("TRACE"));
assert!(result.contains("loop.rs:app::util:55"));
}
}