1use std::cmp;
2
3const DELIMITER: f64 = 1000_f64;
4const UNITS: &[&str] = &["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
5
6pub fn bytes(n: f64) -> String {
9 let sign = if n.is_sign_positive() { "" } else { "-" };
10 let n = n.abs();
11 if n < 1_f64 {
12 return format!("{}{} {}", sign, n, "B");
13 }
14 let exp = cmp::min(
15 (n.ln() / DELIMITER.ln()).floor() as i32,
16 (UNITS.len() - 1) as i32,
17 );
18 let bytes = format!("{:.2}", n / DELIMITER.powi(exp))
19 .parse::<f64>()
20 .unwrap()
21 * 1_f64;
22 let unit = UNITS[exp as usize];
23 format!("{}{} {}", sign, bytes, unit)
24}
25
26#[test]
27fn test_humanize_bytes() {
28 assert!(bytes(100000.0) == "100 kB");
29 assert!(bytes(490652508160.0) == "490.65 GB");
30 assert!(bytes(252868079616.0) == "252.87 GB");
31 assert!(bytes(227876253696.0) == "227.88 GB");
32}