file_size/
lib.rs

1/*!
2
3Format a file size into 4 characters.
4
5Examples:
6
7```
8use file_size::fit_4;
9
10assert_eq!(&fit_4(999), "999");
11assert_eq!(&fit_4(12345), "12K");
12assert_eq!(&fit_4(999_999), "1.0M");
13assert_eq!(&fit_4(7_155_456_789_012), "7.2T");
14```
15
16!*/
17
18
19/// produce the most precise and nearest ISO size writing
20/// fitting in 4 characters of the given integer size
21pub fn fit_4(size: u64) -> String {
22    // if you have more efficient or prettier, please tell me
23    match size {
24        0..=9_999 => size.to_string(),
25        10_000..=999_499 => format!("{:.0}K", (size as f64) / 1_000.0),
26        999_500..=9_950_000 => format!("{:.1}M", (size as f64) / 1_000_000.0),
27        9_950_001..=999_499_999 => format!("{:.0}M", (size as f64) / 1_000_000.0),
28        999_500_000..=9_950_000_000 => format!("{:.1}G", (size as f64) / 1_000_000_000.0),
29        9_950_000_001..=999_499_999_999 => format!("{:.0}G", (size as f64) / 1_000_000_000.0),
30        999_500_000_000..=9_950_000_000_000 => format!("{:.1}T", (size as f64) / 1_000_000_000_000.0),
31        9_950_000_000_001..=999_499_999_999_999 => format!("{:.0}T", (size as f64) / 1_000_000_000_000.0),
32        999_500_000_000_000..=9_950_000_000_000_000 => format!("{:.1}P", (size as f64) / 1_000_000_000_000_000.0),
33        9_950_000_000_000_001..=999_499_999_999_999_935 => format!("{:.0}P", (size as f64) / 1_000_000_000_000_000.0),
34        _ => "huge".to_string(), // good enough to me
35    }
36}
37
38#[cfg(test)]
39mod file_size_display_tests {
40
41    use super::*;
42
43    fn check(size: u64, s: &str) {
44        assert_eq!(&fit_4(size), s);
45    }
46
47    #[test]
48    fn check_size_displays() {
49        check(1, "1");
50        check(12, "12");
51        check(183, "183");
52        check(999, "999");
53        check(9999, "9999");
54        check(10000, "10K");
55        check(12345, "12K");
56        check(56789, "57K");
57        check(456_789, "457K");
58        check(666_666, "667K");
59        check(999_000, "999K");
60        check(999_499, "999K");
61        check(999_500, "1.0M");
62        check(999_999, "1.0M");
63        check(3_456_789, "3.5M");
64        check(9_556_789, "9.6M");
65        check(9_950_000, "9.9M");
66        check(9_950_001, "10M");
67        check(9_956_789, "10M");
68        check(12_345_678, "12M");
69        check(99_999_999, "100M");
70        check(212_345_678, "212M");
71        check(999_000_999, "999M");
72        check(999_499_999, "999M");
73        check(999_500_000, "1.0G");
74        check(999_999_999, "1.0G");
75        check(3_456_789_012, "3.5G");
76        check(9_950_000_000, "9.9G");
77        check(9_950_000_001, "10G");
78        check(23_456_789_012, "23G");
79        check(123_456_789_012, "123G");
80        check(999_499_999_999, "999G");
81        check(999_500_000_000, "1.0T");
82        check(7_155_456_789_012, "7.2T");
83        check(9_950_000_000_000, "9.9T");
84        check(9_950_000_000_001, "10T");
85        check(87_123_456_789_012, "87T");
86        check(487_123_456_789_012, "487T");
87        check(999_499_999_999_999, "999T");
88        check(999_500_000_000_000, "1.0P");
89        check(8_987_123_456_789_012, "9.0P");
90        check(9_950_000_000_000_000, "9.9P");
91        check(9_950_000_000_000_001, "10P");
92        check(368_640_042_346_630_455, "369P");
93        check(999_499_999_999_999_935, "999P");
94        check(999_499_999_999_999_936, "huge");
95        check(1_675_359_327_149_419_060, "huge");
96    }
97}