Skip to main content

spacecrab_core/
formatter.rs

1pub struct SizeFormatter;
2
3impl SizeFormatter {
4    pub fn format(bytes: u64) -> String {
5        const UNITS: [&str; 6] = ["B", "KiB", "MiB", "GiB", "TiB", "PiB"];
6        let mut size = bytes as f64;
7        let mut idx = 0;
8        
9        while idx + 1 < UNITS.len() && size >= 1024.0 {
10            size /= 1024.0;
11            idx += 1
12        }
13        
14        if idx == 0 {
15            format!("{} {}", bytes, UNITS[idx])
16        } else {
17            format!("{:.2} {}", size, UNITS[idx])
18        }
19    }
20}
21
22#[cfg(test)]
23mod tests {
24    use super::SizeFormatter;
25
26    #[test]
27    fn format_bytes_under_1kb() {
28        assert_eq!(SizeFormatter::format(0), "0 B");
29        assert_eq!(SizeFormatter::format(1), "1 B");
30        assert_eq!(SizeFormatter::format(500), "500 B");
31        assert_eq!(SizeFormatter::format(1023), "1023 B");
32    }
33
34    #[test]
35    fn format_exact_kib() {
36        assert_eq!(SizeFormatter::format(1024), "1.00 KiB");
37        assert_eq!(SizeFormatter::format(1024 * 1024), "1.00 MiB");
38        assert_eq!(SizeFormatter::format(1024 * 1024 * 1024), "1.00 GiB");
39        assert_eq!(SizeFormatter::format(1024_u64.pow(4)), "1.00 TiB");
40    }
41
42    #[test]
43    fn format_partial_units() {
44        assert_eq!(SizeFormatter::format(1536), "1.50 KiB");
45        assert_eq!(SizeFormatter::format(5 * 1024 * 1024), "5.00 MiB");
46        let bytes = 10 * 1024 * 1024 * 1024 + 512 * 1024 * 1024; // 10.5 GiB
47        assert_eq!(SizeFormatter::format(bytes), "10.50 GiB");
48    }
49
50    #[test]
51    fn format_large_values() {
52        let one_pib = 1024_u64.pow(5);
53        assert_eq!(SizeFormatter::format(one_pib), "1.00 PiB");
54
55        let almost_two_pib = one_pib * 2 + 100;
56        assert_eq!(SizeFormatter::format(almost_two_pib), "2.00 PiB");
57    }
58}