pub fn human_bytes(bytes: u64) -> String {
if bytes >= 1_073_741_824 {
format!("{:.1} GB", bytes as f64 / 1_073_741_824.0)
} else if bytes >= 1_048_576 {
format!("{:.1} MB", bytes as f64 / 1_048_576.0)
} else if bytes >= 1024 {
format!("{:.1} KB", bytes as f64 / 1024.0)
} else {
format!("{bytes} B")
}
}
pub fn human_bytes_compact(bytes: u64) -> String {
const K: f64 = 1024.0;
let f = bytes as f64;
if f < K {
format!("{bytes}B")
} else if f < K * K {
format!("{:.1}K", f / K)
} else if f < K * K * K {
format!("{:.1}M", f / (K * K))
} else {
format!("{:.1}G", f / (K * K * K))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn human_bytes_compact_picks_the_right_unit_at_each_threshold() {
assert_eq!(human_bytes_compact(0), "0B");
assert_eq!(human_bytes_compact(1), "1B");
assert_eq!(human_bytes_compact(1023), "1023B");
assert_eq!(human_bytes_compact(1024), "1.0K");
assert_eq!(human_bytes_compact(1536), "1.5K");
assert_eq!(human_bytes_compact(1024 * 1024), "1.0M");
assert_eq!(human_bytes_compact(5 * 1024 * 1024), "5.0M");
assert_eq!(human_bytes_compact(1024u64.pow(3)), "1.0G");
assert_eq!(human_bytes_compact(5_368_709_120), "5.0G");
}
#[test]
fn human_bytes_spaced_flavor_matches_units_and_spacing() {
assert_eq!(human_bytes(42), "42 B");
assert_eq!(human_bytes(1536), "1.5 KB");
assert_eq!(human_bytes(5 * 1024 * 1024), "5.0 MB");
assert_eq!(human_bytes(7_516_192_768), "7.0 GB");
}
}