use crate::Level;
use std::time::SystemTime;
#[derive(Clone, Debug)]
pub struct Record {
pub level: Level,
pub args: String,
pub file: &'static str,
pub line: u32,
pub module_path: &'static str,
pub timestamp: SystemTime,
}
pub trait Formatter: Send + Sync {
fn format(&self, record: &Record) -> String;
}
#[derive(Debug)]
pub struct HumanReadableFormatter;
impl Formatter for HumanReadableFormatter {
fn format(&self, record: &Record) -> String {
format!("[{:?}] {}", record.level, record.args)
}
}
#[derive(Debug)]
pub struct JsonFormatter;
impl Formatter for JsonFormatter {
fn format(&self, record: &Record) -> String {
let escaped_args = record.args.replace('"', "\\\"");
format!(
r#"{{"timestamp":{:?}, "level":"{:?}", "message":"{}", "module":"{}"}}"#,
record.timestamp, record.level, escaped_args, record.module_path
)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Level;
fn create_test_record(level: Level, message: &str) -> Record {
Record {
level,
args: message.to_string(),
file: "main.rs",
line: 10,
module_path: "app::network",
timestamp: SystemTime::UNIX_EPOCH, }
}
#[test]
fn test_human_readable_formatter() {
let record = create_test_record(Level::Debug, "System initialized");
let formatter = HumanReadableFormatter;
assert_eq!(formatter.format(&record), "[Debug] System initialized");
}
#[test]
fn test_json_formatter() {
let record = create_test_record(Level::Info, "User login");
let formatter = JsonFormatter;
let result = formatter.format(&record);
assert!(result.contains(r#""level":"Info""#));
assert!(result.contains(r#""message":"User login""#));
assert!(result.starts_with('{') && result.ends_with('}'));
}
}