From 76116ed5ecec466b6755f5edb31d016d86dae22b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20M=2E=20Bezerra?= Date: Mon, 4 Sep 2023 20:40:00 -0300 Subject: [PATCH 1/3] re-add our size unit code from 368a776 --- src/utils/formatting.rs | 72 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/src/utils/formatting.rs b/src/utils/formatting.rs index 7a409e5..c708edd 100644 --- a/src/utils/formatting.rs +++ b/src/utils/formatting.rs @@ -1,4 +1,4 @@ -use std::{borrow::Cow, fmt::Display, path::Path}; +use std::{borrow::Cow, cmp, fmt::Display, path::Path}; use crate::CURRENT_DIRECTORY; @@ -86,3 +86,73 @@ pub fn nice_directory_display(path: &Path) -> Cow { to_utf(path) } } + +/// Struct useful to printing bytes as kB, MB, GB, etc. +pub struct Bytes { + bytes: f64, +} + +impl Bytes { + const UNIT_PREFIXES: [&'static str; 6] = ["", "k", "M", "G", "T", "P"]; + + /// Create a new Bytes. + pub fn new(bytes: u64) -> Self { + Self { bytes: bytes as f64 } + } +} + +impl std::fmt::Display for Bytes { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let num = self.bytes; + 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]) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_pretty_bytes_formatting() { + fn format_bytes(bytes: u64) -> String { + format!("{}", Bytes::new(bytes)) + } + let b = 1; + let kb = b * 1000; + let mb = kb * 1000; + let gb = mb * 1000; + + 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)); + + // 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)); + // 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)); + // 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)); + } +} 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 2/3] 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)); } } From cbd327aad760d4b38b951087f02457cd9760fe6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20M=2E=20Bezerra?= Date: Mon, 4 Sep 2023 21:15:57 -0300 Subject: [PATCH 3/3] replace usage of `ubyte` by our own `Bytes` formatter --- Cargo.lock | 7 ------- Cargo.toml | 1 - src/archive/tar.rs | 5 ++--- src/archive/zip.rs | 5 ++--- src/utils/mod.rs | 4 +++- 5 files changed, 7 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e4fa540..497ff5a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -735,7 +735,6 @@ dependencies = [ "tempfile", "test-strategy", "time", - "ubyte", "xz2", "zip", "zstd", @@ -1188,12 +1187,6 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "ubyte" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c81f0dae7d286ad0d9366d7679a77934cfc3cf3a8d67e82669794412b2368fe6" - [[package]] name = "unarray" version = "0.1.4" diff --git a/Cargo.toml b/Cargo.toml index a15de74..f87207a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,6 @@ snap = "1.1.0" tar = "0.4.40" tempfile = "3.8.0" time = { version = "0.3.28", default-features = false } -ubyte = { version = "0.10.3", default-features = false } xz2 = "0.1.7" zip = { version = "0.6.6", default-features = false, features = ["time"] } zstd = { version = "0.12.4", default-features = false } diff --git a/src/archive/tar.rs b/src/archive/tar.rs index 54f144f..d376288 100644 --- a/src/archive/tar.rs +++ b/src/archive/tar.rs @@ -10,13 +10,12 @@ use std::{ use fs_err as fs; use same_file::Handle; -use ubyte::ToByteUnit; use crate::{ error::FinalError, info, list::FileInArchive, - utils::{self, EscapedPathDisplay, FileVisibilityPolicy}, + utils::{self, Bytes, EscapedPathDisplay, FileVisibilityPolicy}, warning, }; @@ -41,7 +40,7 @@ pub fn unpack_archive(reader: Box, output_folder: &Path, quiet: bool) inaccessible, "{:?} extracted. ({})", utils::strip_cur_dir(&output_folder.join(file.path()?)), - file.size().bytes(), + Bytes::new(file.size()), ); files_unpacked += 1; diff --git a/src/archive/zip.rs b/src/archive/zip.rs index 47d7363..60cc440 100644 --- a/src/archive/zip.rs +++ b/src/archive/zip.rs @@ -14,7 +14,6 @@ use filetime::{set_file_mtime, FileTime}; use fs_err as fs; use same_file::Handle; use time::OffsetDateTime; -use ubyte::ToByteUnit; use zip::{self, read::ZipFile, DateTime, ZipArchive}; use crate::{ @@ -22,7 +21,7 @@ use crate::{ info, list::FileInArchive, utils::{ - self, cd_into_same_dir_as, get_invalid_utf8_paths, pretty_format_list_of_paths, strip_cur_dir, + self, cd_into_same_dir_as, get_invalid_utf8_paths, pretty_format_list_of_paths, strip_cur_dir, Bytes, EscapedPathDisplay, FileVisibilityPolicy, }, warning, @@ -74,7 +73,7 @@ where inaccessible, "{:?} extracted. ({})", file_path.display(), - file.size().bytes() + Bytes::new(file.size()), ); } diff --git a/src/utils/mod.rs b/src/utils/mod.rs index a601287..3487b0c 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -10,7 +10,9 @@ mod fs; mod question; pub use file_visibility::FileVisibilityPolicy; -pub use formatting::{nice_directory_display, pretty_format_list_of_paths, strip_cur_dir, to_utf, EscapedPathDisplay}; +pub use formatting::{ + nice_directory_display, pretty_format_list_of_paths, strip_cur_dir, to_utf, Bytes, EscapedPathDisplay, +}; pub use fs::{ cd_into_same_dir_as, clear_path, create_dir_if_non_existent, is_symlink, remove_file_or_dir, try_infer_extension, };