1pub fn sizify(bytes: u64, add_i: bool) -> String {
18 if bytes == 0 {
19 return "0".to_string();
20 }
21
22 let prefixes = ["", "K", "M", "G", "T", "P", "E", "Z", "Y", "R", "Q"];
23 let prefix_index = ((bytes as f64).log2() / 10.0)
24 .floor()
25 .min(prefixes.len() as f64 - 1.0) as usize;
26 let prefix_index_translated = 2_i64.pow(10 * prefix_index as u32);
27 let decimal_points = ((2.0
28 - (bytes as f64 / prefix_index_translated as f64)
29 .log10()
30 .floor()) as i32)
31 .max(0);
32
33 let size = ((bytes as f64 / prefix_index_translated as f64) * 10_f64.powi(decimal_points)).ceil()
34 / 10_f64.powi(decimal_points);
35 let prefix = prefixes[prefix_index];
36 let suffix = if prefix_index > 0 && add_i { "i" } else { "" };
37
38 format!("{}{}{}", size, prefix, suffix)
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44
45 #[test]
46 fn test_sizify_zero_bytes() {
47 assert_eq!(sizify(0, false), "0");
48 }
49
50 #[test]
51 fn test_sizify_small_values() {
52 assert_eq!(sizify(1000, false), "1000");
53 assert_eq!(sizify(1024, false), "1K");
54 }
55
56 #[test]
57 fn test_sizify_larger_values() {
58 assert_eq!(sizify(1048576, false), "1M");
59 assert_eq!(sizify(1073741824, false), "1G");
60 assert_eq!(sizify(1099511627776, false), "1T");
61 assert_eq!(sizify(1125899906842624, false), "1P");
62 assert_eq!(sizify(1152921504606846976, false), "1E");
63 }
64
65 #[test]
66 fn test_sizify_add_i_suffix() {
67 assert_eq!(sizify(1024, true), "1Ki");
68 assert_eq!(sizify(1048576, true), "1Mi");
69 assert_eq!(sizify(1073741824, true), "1Gi");
70 }
71
72 #[test]
73 fn test_sizify_no_i_suffix() {
74 assert_eq!(sizify(1024, false), "1K");
75 assert_eq!(sizify(1048576, false), "1M");
76 assert_eq!(sizify(1073741824, false), "1G");
77 }
78
79 #[test]
80 fn test_sizify_decimal_points() {
81 assert_eq!(sizify(1500, false), "1.47K");
82 assert_eq!(sizify(1500000, false), "1.44M");
83 assert_eq!(sizify(1500000000, false), "1.4G");
84 }
85
86 #[test]
87 fn test_sizify_edge_cases() {
88 assert_eq!(sizify(1, false), "1");
89 assert_eq!(sizify(1023, false), "1023");
90 assert_eq!(sizify(1025, false), "1.01K");
91 }
92}