112 lines
2.9 KiB
Rust
112 lines
2.9 KiB
Rust
|
|
//! 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<u64> {
|
||
|
|
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");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|