diff --git a/CHANGELOG.md b/CHANGELOG.md index c0f3166..fe058ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,6 +73,7 @@ Categories Used: - Apply clippy lints [\#273](https://github.com/ouch-org/ouch/pull/273) ([figsoda](https://github.com/figsoda)) - Warn user if file extension is passed as file name [\#277](https://github.com/ouch-org/ouch/pull/277) ([marcospb19](https://github.com/marcospb19)) - Check for errors when setting the last modified time [\#278](https://github.com/ouch-org/ouch/pull/278) ([marcospb19](https://github.com/marcospb19)) +- Use to the humansize crate for formatting human-readable file sizes [\#281](https://github.com/ouch-org/ouch/pull/281) ([figsoda](https://github.com/figsoda)) ### Tweaks diff --git a/Cargo.lock b/Cargo.lock index a41d737..6be10b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -328,6 +328,15 @@ dependencies = [ "libc", ] +[[package]] +name = "humansize" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a866837516f34ad34fb221f3ee01fd0db75f2c2f6abeda2047dc6963fb04ad9a" +dependencies = [ + "libm", +] + [[package]] name = "ignore" version = "0.4.18" @@ -420,6 +429,12 @@ version = "0.2.135" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c" +[[package]] +name = "libm" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "292a948cd991e376cf75541fe5b97a1081d713c618b4f1b9500f8844e49eb565" + [[package]] name = "libz-sys" version = "1.1.8" @@ -530,6 +545,7 @@ dependencies = [ "filetime", "flate2", "fs-err", + "humansize", "ignore", "indicatif", "infer", diff --git a/Cargo.toml b/Cargo.toml index 701d461..d6b216c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ bzip2 = "0.4.3" clap = { version = "4.0.13", features = ["derive", "env"] } flate2 = { version = "1.0.24", default-features = false } fs-err = "2.8.1" +humansize = "2.1.0" libc = "0.2.135" linked-hash-map = "0.5.6" lzzzz = "1.0.3" diff --git a/src/archive/tar.rs b/src/archive/tar.rs index 85b41b7..a845e6d 100644 --- a/src/archive/tar.rs +++ b/src/archive/tar.rs @@ -9,12 +9,13 @@ use std::{ }; use fs_err as fs; +use humansize::{format_size, DECIMAL}; use crate::{ error::FinalError, info, list::FileInArchive, - utils::{self, Bytes, FileVisibilityPolicy}, + utils::{self, FileVisibilityPolicy}, }; /// Unpacks the archive given by `archive` into the folder given by `into`. @@ -43,7 +44,8 @@ pub fn unpack_archive( @display_handle, inaccessible, "{:?} extracted. ({})", - utils::strip_cur_dir(&output_folder.join(file.path()?)), Bytes::new(file.size()) + utils::strip_cur_dir(&output_folder.join(file.path()?)), + format_size(file.size(), DECIMAL), ); files_unpacked.push(file_path); diff --git a/src/archive/zip.rs b/src/archive/zip.rs index fd0ecfb..fb0921d 100644 --- a/src/archive/zip.rs +++ b/src/archive/zip.rs @@ -13,6 +13,7 @@ use std::{ use filetime::{set_file_mtime, FileTime}; use fs_err as fs; +use humansize::{format_size, DECIMAL}; use zip::{self, read::ZipFile, DateTime, ZipArchive}; use crate::{ @@ -20,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, to_utf, Bytes, + self, cd_into_same_dir_as, get_invalid_utf8_paths, pretty_format_list_of_paths, strip_cur_dir, to_utf, FileVisibilityPolicy, }, }; @@ -73,7 +74,8 @@ where @display_handle, inaccessible, "{:?} extracted. ({})", - file_path.display(), Bytes::new(file.size()) + file_path.display(), + format_size(file.size(), DECIMAL), ); let mut output_file = fs::File::create(file_path)?; diff --git a/src/utils/formatting.rs b/src/utils/formatting.rs index e49a54c..57c9bcd 100644 --- a/src/utils/formatting.rs +++ b/src/utils/formatting.rs @@ -1,4 +1,4 @@ -use std::{borrow::Cow, cmp, path::Path}; +use std::{borrow::Cow, path::Path}; use crate::CURRENT_DIRECTORY; @@ -48,73 +48,3 @@ 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)); - } -} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 2df3936..05e325c 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -10,7 +10,7 @@ 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, Bytes}; +pub use formatting::{nice_directory_display, pretty_format_list_of_paths, strip_cur_dir, to_utf}; pub use fs::{ cd_into_same_dir_as, clear_path, create_dir_if_non_existent, dir_is_empty, is_symlink, try_infer_extension, };