1
use std::fmt;
2

            
3
/// Formats bytes into human-readable format using decimal units (GB, MB, KB, bytes)
4
///
5
/// Note: This uses decimal units (1 KB = 1000 bytes) rather than binary units (1 KiB = 1024 bytes).
6
pub struct BytesFormatter(pub usize);
7

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

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

            
27
pub struct LargeFormatter<T: ToString>(pub T);
28

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

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

            
42
4
        Ok(())
43
4
    }
44
}
45

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

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

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