Merge pull request #502 from ouch-org/fix-size-unit-inconsistency

Fix size unit inconsistency
This commit is contained in:
João Marcos 2023-09-07 16:12:20 -03:00 committed by GitHub
commit 9507c4d93a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 86 additions and 16 deletions

7
Cargo.lock generated
View File

@ -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"

View File

@ -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 }

View File

@ -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<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;

View File

@ -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()),
);
}

View File

@ -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,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));
}
}

View File

@ -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,
};