1pub fn sizify(bytes: u64, add_i: bool) -> String {
20 if bytes == 0 {
21 return "0".to_string();
22 }
23
24 let prefixes = ["", "K", "M", "G", "T", "P", "E", "Z", "Y", "R", "Q"];
25 let prefix_index = (bytes.ilog2() as usize / 10).min(prefixes.len() - 1);
26 let prefix_index_translated = 2_u64.pow(10 * prefix_index as u32);
27 let decimal_points = (2
28 - (bytes / prefix_index_translated)
29 .checked_ilog10()
30 .unwrap_or(0) 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
36 let mut result = String::new();
37 result.push_str(&size.to_string()); result.push_str(prefixes[prefix_index]); if prefix_index > 0 && add_i {
40 result.push('i'); }
42
43 result
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49
50 #[test]
51 fn test_sizify_zero_bytes() {
52 assert_eq!(sizify(0, false), "0");
53 }
54
55 #[test]
56 fn test_sizify_small_values() {
57 assert_eq!(sizify(1000, false), "1000");
58 assert_eq!(sizify(1024, false), "1K");
59 }
60
61 #[test]
62 fn test_sizify_larger_values() {
63 assert_eq!(sizify(1048576, false), "1M");
64 assert_eq!(sizify(1073741824, false), "1G");
65 assert_eq!(sizify(1099511627776, false), "1T");
66 assert_eq!(sizify(1125899906842624, false), "1P");
67 assert_eq!(sizify(1152921504606846976, false), "1E");
68 }
69
70 #[test]
71 fn test_sizify_add_i_suffix() {
72 assert_eq!(sizify(1024, true), "1Ki");
73 assert_eq!(sizify(1048576, true), "1Mi");
74 assert_eq!(sizify(1073741824, true), "1Gi");
75 }
76
77 #[test]
78 fn test_sizify_no_i_suffix() {
79 assert_eq!(sizify(1024, false), "1K");
80 assert_eq!(sizify(1048576, false), "1M");
81 assert_eq!(sizify(1073741824, false), "1G");
82 }
83
84 #[test]
85 fn test_sizify_decimal_points() {
86 assert_eq!(sizify(1500, false), "1.47K");
87 assert_eq!(sizify(1500000, false), "1.44M");
88 assert_eq!(sizify(1500000000, false), "1.4G");
89 }
90
91 #[test]
92 fn test_sizify_edge_cases() {
93 assert_eq!(sizify(1, false), "1");
94 assert_eq!(sizify(1023, false), "1023");
95 assert_eq!(sizify(1025, false), "1.01K");
96 }
97}