1const SUFFIXES: [&str; 9] = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
4const BINARY_SUFFIXES: [&str; 9] = ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"];
5
6pub fn decimal(size: u64) -> String {
8 format_size(size, 1000.0, &SUFFIXES)
9}
10
11pub fn binary(size: u64) -> String {
13 format_size(size, 1024.0, &BINARY_SUFFIXES)
14}
15
16fn format_size(size: u64, divisor: f64, suffixes: &[&str]) -> String {
17 if size == 0 {
18 return format!("0 {}", suffixes[0]);
19 }
20
21 let size_f = size as f64;
22 let i = (size_f.log(divisor).floor() as usize).min(suffixes.len() - 1);
23
24 if i == 0 {
25 format!("{} {}", size, suffixes[0])
26 } else {
27 let val = size_f / divisor.powi(i as i32);
28 format!("{:.1} {}", val, suffixes[i])
29 }
30}
31
32#[cfg(test)]
33mod tests {
34 use super::*;
35
36 #[test]
37 fn test_decimal() {
38 assert_eq!(decimal(0), "0 B");
39 assert_eq!(decimal(500), "500 B");
40 assert_eq!(decimal(1000), "1.0 kB");
41 assert_eq!(decimal(1500), "1.5 kB");
42 assert_eq!(decimal(1_000_000), "1.0 MB");
43 }
44
45 #[test]
46 fn test_binary() {
47 assert_eq!(binary(0), "0 B");
48 assert_eq!(binary(1024), "1.0 KiB");
49 assert_eq!(binary(1536), "1.5 KiB");
50 assert_eq!(binary(1_048_576), "1.0 MiB");
51 }
52}