formatting: fix gibibytes vs gigabytes issue

This commit is contained in:
João M. Bezerra 2023-09-04 20:54:49 -03:00
parent 76116ed5ec
commit 693167e933

View File

@ -88,31 +88,35 @@ pub fn nice_directory_display(path: &Path) -> Cow<str> {
}
/// Struct useful to printing bytes as kB, MB, GB, etc.
pub struct Bytes {
bytes: f64,
}
pub struct Bytes(f64);
impl Bytes {
const UNIT_PREFIXES: [&'static str; 6] = ["", "k", "M", "G", "T", "P"];
const UNIT_PREFIXES: [&'static str; 6] = ["", "ki", "Mi", "Gi", "Ti", "Pi"];
/// Create a new Bytes.
pub fn new(bytes: u64) -> Self {
Self { bytes: bytes as f64 }
Self(bytes as f64)
}
}
impl std::fmt::Display for Bytes {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let num = self.bytes;
let &Self(num) = self;
debug_assert!(num >= 0.0);
if num < 1_f64 {
return write!(f, "{} B", num);
}
let delimiter = 1000_f64;
let exponent = cmp::min((num.ln() / 6.90775).floor() as i32, 4);
write!(f, "{:.2} ", num / delimiter.powi(exponent))?;
write!(f, "{}B", Bytes::UNIT_PREFIXES[exponent as usize])
write!(
f,
"{:.2} {}B",
num / delimiter.powi(exponent),
Bytes::UNIT_PREFIXES[exponent as usize]
)
}
}
@ -133,26 +137,30 @@ mod tests {
assert_eq!("0 B", format_bytes(0)); // This is weird
assert_eq!("1.00 B", format_bytes(b));
assert_eq!("999.00 B", format_bytes(b * 999));
assert_eq!("12.00 MB", format_bytes(mb * 12));
assert_eq!("123.00 MB", format_bytes(mb * 123));
assert_eq!("5.50 MB", format_bytes(mb * 5 + kb * 500));
assert_eq!("7.54 GB", format_bytes(gb * 7 + 540 * mb));
assert_eq!("1.20 TB", format_bytes(gb * 1200));
assert_eq!("12.00 MiB", format_bytes(mb * 12));
assert_eq!("123.00 MiB", format_bytes(mb * 123));
assert_eq!("5.50 MiB", format_bytes(mb * 5 + kb * 500));
assert_eq!("7.54 GiB", format_bytes(gb * 7 + 540 * mb));
assert_eq!("1.20 TiB", format_bytes(gb * 1200));
// bytes
assert_eq!("234.00 B", format_bytes(234));
assert_eq!("999.00 B", format_bytes(999));
// kilobytes
assert_eq!("2.23 kB", format_bytes(2234));
assert_eq!("62.50 kB", format_bytes(62500));
assert_eq!("329.99 kB", format_bytes(329990));
assert_eq!("2.23 kiB", format_bytes(2234));
assert_eq!("62.50 kiB", format_bytes(62500));
assert_eq!("329.99 kiB", format_bytes(329990));
// megabytes
assert_eq!("2.75 MB", format_bytes(2750000));
assert_eq!("55.00 MB", format_bytes(55000000));
assert_eq!("987.65 MB", format_bytes(987654321));
assert_eq!("2.75 MiB", format_bytes(2750000));
assert_eq!("55.00 MiB", format_bytes(55000000));
assert_eq!("987.65 MiB", format_bytes(987654321));
// gigabytes
assert_eq!("5.28 GB", format_bytes(5280000000));
assert_eq!("95.20 GB", format_bytes(95200000000));
assert_eq!("302.00 GB", format_bytes(302000000000));
assert_eq!("5.28 GiB", format_bytes(5280000000));
assert_eq!("95.20 GiB", format_bytes(95200000000));
assert_eq!("302.00 GiB", format_bytes(302000000000));
assert_eq!("302.99 GiB", format_bytes(302990000000));
// Weird aproximation cases:
assert_eq!("999.90 GiB", format_bytes(999900000000));
assert_eq!("1.00 TiB", format_bytes(999990000000));
}
}