First Setup

This commit is contained in:
victor 2025-08-26 22:52:37 +02:00
commit 02e552cddd
5 changed files with 202 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

7
Cargo.lock generated Normal file
View File

@ -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"

6
Cargo.toml Normal file
View File

@ -0,0 +1,6 @@
[package]
name = "vlogger"
version = "0.1.0"
edition = "2024"
[dependencies]

11
README.md Normal file
View File

@ -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

177
src/lib.rs Normal file
View File

@ -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);
}
}