Skip to content

Commit

Permalink
Merge pull request #502 from ouch-org/fix-size-unit-inconsistency
Browse files Browse the repository at this point in the history
Fix size unit inconsistency
  • Loading branch information
marcospb19 authored Sep 7, 2023
2 parents 3706f0d + cbd327a commit 9507c4d
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 16 deletions.
7 changes: 0 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
5 changes: 2 additions & 3 deletions src/archive/tar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

Expand All @@ -41,7 +40,7 @@ pub fn unpack_archive(reader: Box<dyn Read>, 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;
Expand Down
5 changes: 2 additions & 3 deletions src/archive/zip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,14 @@ 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::{
error::FinalError,
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,
Expand Down Expand Up @@ -74,7 +73,7 @@ where
inaccessible,
"{:?} extracted. ({})",
file_path.display(),
file.size().bytes()
Bytes::new(file.size()),
);
}

Expand Down
80 changes: 79 additions & 1 deletion src/utils/formatting.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -86,3 +86,81 @@ pub fn nice_directory_display(path: &Path) -> Cow<str> {
to_utf(path)
}
}

/// Struct useful to printing bytes as kB, MB, GB, etc.
pub struct Bytes(f64);

impl Bytes {
const UNIT_PREFIXES: [&'static str; 6] = ["", "ki", "Mi", "Gi", "Ti", "Pi"];

/// Create a new Bytes.
pub fn new(bytes: u64) -> Self {
Self(bytes as f64)
}
}

impl std::fmt::Display for Bytes {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
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} {}B",
num / delimiter.powi(exponent),
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 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 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 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 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));
}
}
4 changes: 3 additions & 1 deletion src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down

0 comments on commit 9507c4d

Please sign in to comment.