Skip to main content

forge_guard/utils/
formatting.rs

1//! Formatting utilities for output display.
2
3/// Format a duration in seconds to a human-readable string.
4pub fn format_duration(secs: f64) -> String {
5    if secs < 1.0 {
6        format!("{:.0}ms", secs * 1000.0)
7    } else if secs < 60.0 {
8        format!("{:.1}s", secs)
9    } else if secs < 3600.0 {
10        let minutes = (secs / 60.0) as u64;
11        let seconds = (secs % 60.0) as u64;
12        format!("{}m {}s", minutes, seconds)
13    } else {
14        let hours = (secs / 3600.0) as u64;
15        let minutes = ((secs % 3600.0) / 60.0) as u64;
16        format!("{}h {}m", hours, minutes)
17    }
18}
19
20/// Format a number with comma separators.
21pub fn format_number(n: u64) -> String {
22    let s = n.to_string();
23    let mut result = String::new();
24    for (i, c) in s.chars().rev().enumerate() {
25        if i > 0 && i % 3 == 0 {
26            result.insert(0, ',');
27        }
28        result.insert(0, c);
29    }
30    result
31}
32
33/// Format a percentage value.
34pub fn format_pct(value: f64) -> String {
35    format!("{:.1}%", value * 100.0)
36}
37
38/// Format bytes to a human-readable size.
39pub fn format_bytes(bytes: u64) -> String {
40    const UNITS: &[&str] = &["B", "KB", "MB", "GB", "TB"];
41    let mut size = bytes as f64;
42    let mut unit_idx = 0;
43
44    while size >= 1024.0 && unit_idx < UNITS.len() - 1 {
45        size /= 1024.0;
46        unit_idx += 1;
47    }
48
49    if unit_idx == 0 {
50        format!("{} {}", bytes, UNITS[unit_idx])
51    } else {
52        format!("{:.2} {}", size, UNITS[unit_idx])
53    }
54}