//! Utilities module //! //! This module provides utility functions and helpers. pub mod validation; pub mod serialization; pub mod date; pub mod logging; pub use validation::*; pub use serialization::*; pub use date::*; pub use logging::*; // Re-export other utility functions use uuid::Uuid; /// Generate a new UUID v4 pub fn generate_uuid() -> Uuid { Uuid::new_v4() } /// Format a duration in seconds to a human-readable string pub fn format_duration(seconds: u64) -> String { let hours = seconds / 3600; let minutes = (seconds % 3600) / 60; let secs = seconds % 60; if hours > 0 { format!("{}:{:02}:{:02}", hours, minutes, secs) } else { format!("{}:{:02}", minutes, secs) } } /// Parse a duration string to seconds /// Supports formats: "MM:SS", "HH:MM:SS" pub fn parse_duration(duration_str: &str) -> Option { let parts: Vec<&str> = duration_str.split(':').collect(); match parts.len() { 2 => { // MM:SS format let minutes: u64 = parts[0].parse().ok()?; let seconds: u64 = parts[1].parse().ok()?; Some(minutes * 60 + seconds) } 3 => { // HH:MM:SS format let hours: u64 = parts[0].parse().ok()?; let minutes: u64 = parts[1].parse().ok()?; let seconds: u64 = parts[2].parse().ok()?; Some(hours * 3600 + minutes * 60 + seconds) } _ => None, } } /// Format a file size in bytes to a human-readable string pub fn format_file_size(bytes: u64) -> String { const UNITS: &[&str] = &["B", "KB", "MB", "GB", "TB"]; const THRESHOLD: f64 = 1024.0; if bytes == 0 { return "0 B".to_string(); } let bytes_f64 = bytes as f64; let exp = (bytes_f64.ln() / THRESHOLD.ln()) as u32; let exp = exp.min((UNITS.len() - 1) as u32); let value = bytes_f64 / THRESHOLD.powi(exp as i32); format!("{:.2} {}", value, UNITS[exp as usize]) } #[cfg(test)] mod tests { use super::*; #[test] fn test_generate_uuid() { let uuid1 = generate_uuid(); let uuid2 = generate_uuid(); assert_ne!(uuid1, uuid2); } #[test] fn test_format_duration() { assert_eq!(format_duration(0), "0:00"); assert_eq!(format_duration(65), "1:05"); assert_eq!(format_duration(3665), "1:01:05"); assert_eq!(format_duration(3600), "1:00:00"); } #[test] fn test_parse_duration() { assert_eq!(parse_duration("1:05"), Some(65)); assert_eq!(parse_duration("1:01:05"), Some(3665)); assert_eq!(parse_duration("invalid"), None); assert_eq!(parse_duration("1:2:3:4"), None); } #[test] fn test_format_file_size() { assert_eq!(format_file_size(0), "0 B"); assert_eq!(format_file_size(1024), "1.00 KB"); assert_eq!(format_file_size(1048576), "1.00 MB"); assert_eq!(format_file_size(1073741824), "1.00 GB"); } }