1
use std::fmt;
2

            
3
/// Formats bytes into human-readable format using decimal units (GB, MB, KB, bytes)
4
pub struct BytesFormatter(pub usize);
5

            
6
impl fmt::Display for BytesFormatter {
7
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8
        const KB: usize = 1_000;
9
        const MB: usize = 1_000_000;
10
        const GB: usize = 1_000_000_000;
11

            
12
        // Choose appropriate unit based on size for best readability
13
        if self.0 >= GB {
14
            write!(f, "{:.2} GB", self.0 as f64 / GB as f64)
15
        } else if self.0 >= MB {
16
            write!(f, "{:.2} MB", self.0 as f64 / MB as f64)
17
        } else if self.0 >= KB {
18
            write!(f, "{:.2} KB", self.0 as f64 / KB as f64)
19
        } else {
20
            write!(f, "{} bytes", self.0)
21
        }
22
    }
23
}
24

            
25
pub struct LargeFormatter<T: ToString>(pub T);
26

            
27
impl<T: ToString> fmt::Display for LargeFormatter<T> {
28
4
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29
4
        let num_str = self.0.to_string();
30

            
31
        // Add spaces every three digits from the right
32
4
        let len = num_str.len();
33
19
        for (i, ch) in num_str.chars().enumerate() {
34
19
            if i > 0 && (len - i) % 3 == 0 {
35
4
                write!(f, ",")?;
36
15
            }
37
19
            write!(f, "{}", ch)?;
38
        }
39

            
40
4
        Ok(())
41
4
    }
42
}
43

            
44
#[cfg(test)]
45
mod tests {
46
    use super::*;
47

            
48
    #[test]
49
1
    fn test_large_formatter_small_numbers() {
50
1
        assert_eq!(format!("{}", LargeFormatter(0)), "0");
51
1
        assert_eq!(format!("{}", LargeFormatter(123)), "123");
52
1
    }
53

            
54
    #[test]
55
1
    fn test_large_formatter_millions() {
56
1
        assert_eq!(format!("{}", LargeFormatter(1234567)), "1,234,567");
57
1
        assert_eq!(format!("{}", LargeFormatter(12345678)), "12,345,678");
58
1
    }
59
}