From 693167e933da735ce77627a339afb0b440eb9c22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20M=2E=20Bezerra?= Date: Mon, 4 Sep 2023 20:54:49 -0300 Subject: [PATCH] formatting: fix gibibytes vs gigabytes issue --- src/utils/formatting.rs | 52 ++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/src/utils/formatting.rs b/src/utils/formatting.rs index c708edd..fac5c11 100644 --- a/src/utils/formatting.rs +++ b/src/utils/formatting.rs @@ -88,31 +88,35 @@ pub fn nice_directory_display(path: &Path) -> Cow { } /// 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)); } }