From 02e552cddd65c66ab8d803a65aacf3924749f1e4 Mon Sep 17 00:00:00 2001 From: victor Date: Tue, 26 Aug 2025 22:52:37 +0200 Subject: [PATCH] First Setup --- .gitignore | 1 + Cargo.lock | 7 +++ Cargo.toml | 6 ++ README.md | 11 ++++ src/lib.rs | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 202 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 README.md create mode 100644 src/lib.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..a670227 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "vlogger" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..ae797a5 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "vlogger" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/README.md b/README.md new file mode 100644 index 0000000..32f3168 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# Simple Logger + +A lightweight logging utility for Rust with both printing and string formatting capabilities. + +## Features + +- **Two macros**: `log!` for immediate printing, `msg!` for string formatting +- **Color support**: ANSI color codes for terminal output +- **Multiple log levels**: INFO, DEBUG, WARNING, ERROR, FATAL +- **No external dependencies**: Uses only standard library +- **File/line info**: DEBUG, WARNING, ERROR, and FATAL levels include source location diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..40924bb --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,177 @@ +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", + "WARNING", + "ERROR", + "FATAL", +]; + +pub fn colored(text: &str, color: &str) -> String { + // For terminals: use ANSI escape codes + let ansi_code = match color { + "black" => "30", + "red" => "31", + "green" => "32", + "yellow" => "33", + "blue" => "34", + "purple" => "35", + "cyan" => "36", + "white" => "37", + _ => "0", // default no color + }; + format!("\x1b[{ansi_code}m{text}\x1b[0m") +} + +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)*); + match $level { + $crate::INFO => { + format!( + "[{}] {} | {}", + $crate::colored($crate::LOG_LEVEL[$level], "green"), + $crate::current_timestamp(), + formatted_msg + ) + }, + $crate::DEBUG => { + format!( + "[{}] [{}:{}] {} | {}", + $crate::LOG_LEVEL[$level], + file!(), + line!(), + $crate::current_timestamp(), + formatted_msg + ) + }, + $crate::WARNING => { + format!( + "[{}] [{}:{}] {} | {}", + $crate::colored($crate::LOG_LEVEL[$level], "yellow"), + file!(), + line!(), + $crate::current_timestamp(), + formatted_msg + ) + }, + $crate::ERROR => { + format!( + "[{}] [{}:{}] {} | {}", + $crate::colored($crate::LOG_LEVEL[$level], "red"), + file!(), + line!(), + $crate::current_timestamp(), + formatted_msg + ) + }, + $crate::FATAL => { + format!( + "[{}] [{}:{}] {} | {}", + $crate::colored($crate::LOG_LEVEL[$level], "red"), + file!(), + line!(), + $crate::current_timestamp(), + formatted_msg + ) + }, + _ => { + format!( + "[{}] {} {}", + $crate::LOG_LEVEL[$crate::ERROR], + "logging error: log_level value invalid:", + $level + ) + } + } + }}; +} + +/// 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_colored() { + let red_text = colored("error", "red"); + assert!(red_text.contains("\x1b[31m")); + assert!(red_text.contains("error")); + assert!(red_text.contains("\x1b[0m")); + } + + #[test] + fn test_timestamp() { + let ts = current_timestamp(); + assert!(ts.contains(":")); + // Should be in HH:MM:SS format + assert_eq!(ts.len(), 8); + } +} +