use std::time::{SystemTime, UNIX_EPOCH}; pub const INFO: usize = 0; pub const DEBUG: usize = 1; pub const WARNING: usize = 2; pub const ERROR: usize = 3; pub const FATAL: usize = 4; pub const LOG_LEVEL: [&str; 5] = [ "INFO", "DEBUG", "WARN", "ERROR", "FATAL", ]; pub fn current_timestamp() -> String { let now = SystemTime::now() .duration_since(UNIX_EPOCH) .unwrap_or_default(); let total_seconds = now.as_secs(); let seconds_in_day = total_seconds % 86400; // Seconds within current day let hours = seconds_in_day / 3600; let minutes = (seconds_in_day % 3600) / 60; let seconds = seconds_in_day % 60; format!("{:02}:{:02}:{:02}", hours, minutes, seconds) } /// Creates a formatted log message string and returns it /// /// log_levels are: /// - INFO /// - DEBUG /// - WARNING /// - ERROR /// - FATAL /// /// Returns a formatted string ready for display or further processing. #[macro_export] macro_rules! msg { ($level:expr, $($arg:tt)*) => {{ let formatted_msg = format!($($arg)*); format!( "[{:<5}] [{:<15}:{:<4}] {}\n", $crate::LOG_LEVEL[$level].to_string(), { std::path::Path::new(file!()).file_name().unwrap().to_str().unwrap_or(file!()) }, line!(), formatted_msg ) }}; } /// Creates a formatted log message and prints it to stdout /// /// log_levels are: /// - INFO /// - DEBUG /// - WARNING /// - ERROR /// - FATAL /// /// FATAL will cause the thread to panic and stop execution. #[macro_export] macro_rules! log { ($level:expr, $($arg:tt)*) => {{ let log_message = $crate::msg!($level, $($arg)*); println!("{}", log_message); // Handle FATAL level panic if $level == $crate::FATAL { panic!("Fatal error encountered: {}", format!($($arg)*)); } }}; } #[cfg(test)] mod tests { use super::*; #[test] fn test_msg_macro() { let info_msg = msg!(INFO, "Test info message"); assert!(info_msg.contains("INFO")); assert!(info_msg.contains("Test info message")); let error_msg = msg!(ERROR, "Test error: {}", 42); assert!(error_msg.contains("ERROR")); assert!(error_msg.contains("Test error: 42")); } #[test] fn test_timestamp() { let ts = current_timestamp(); assert!(ts.contains(":")); // Should be in HH:MM:SS format assert_eq!(ts.len(), 8); } }