diff --git a/src/bytes.rs b/src/bytes.rs new file mode 100644 index 000000000..ac1be6e9c --- /dev/null +++ b/src/bytes.rs @@ -0,0 +1,30 @@ +use std::cmp; + +const UNITS: [&str; 4] = ["B", "kB", "MB", "GB"]; + +pub struct Bytes { + bytes: f64, +} + +impl 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, "{}", UNITS[exponent as usize]) + } +} \ No newline at end of file diff --git a/src/compressors/bzip.rs b/src/compressors/bzip.rs index d2a20d0ca..ab6389851 100644 --- a/src/compressors/bzip.rs +++ b/src/compressors/bzip.rs @@ -5,6 +5,7 @@ use colored::Colorize; use super::{Compressor, Entry}; use crate::{ extension::CompressionFormat, + bytes::Bytes, file::File, utils::{check_for_multiple_files, ensure_exists}, }; @@ -22,10 +23,10 @@ impl BzipCompressor { }; println!( - "{}: compressed {:?} into memory ({} bytes)", + "{}: compressed {:?} into memory ({})", "info".yellow(), &path, - contents.len() + Bytes::new(contents.len() as u64) ); Ok(contents) diff --git a/src/compressors/gzip.rs b/src/compressors/gzip.rs index 5dc0ee273..b01208b35 100644 --- a/src/compressors/gzip.rs +++ b/src/compressors/gzip.rs @@ -6,6 +6,7 @@ use super::{Compressor, Entry}; use crate::{ extension::CompressionFormat, file::File, + bytes::Bytes, utils::{check_for_multiple_files, ensure_exists}, }; @@ -27,10 +28,10 @@ impl GzipCompressor { }; println!( - "{}: compressed {:?} into memory ({} bytes)", + "{}: compressed {:?} into memory ({})", "info".yellow(), &path, - bytes.len() + Bytes::new(bytes.len() as u64) ); Ok(bytes) diff --git a/src/compressors/lzma.rs b/src/compressors/lzma.rs index f68a19755..d622ac45c 100644 --- a/src/compressors/lzma.rs +++ b/src/compressors/lzma.rs @@ -6,6 +6,7 @@ use super::{Compressor, Entry}; use crate::{ extension::CompressionFormat, file::File, + bytes::Bytes, utils::{check_for_multiple_files, ensure_exists}, }; @@ -27,10 +28,10 @@ impl LzmaCompressor { }; println!( - "{}: compressed {:?} into memory ({} bytes)", + "{}: compressed {:?} into memory ({})", "info".yellow(), &path, - bytes.len() + Bytes::new(bytes.len() as u64) ); Ok(bytes) diff --git a/src/decompressors/tar.rs b/src/decompressors/tar.rs index fabbea896..2c7ef6446 100644 --- a/src/decompressors/tar.rs +++ b/src/decompressors/tar.rs @@ -8,7 +8,7 @@ use colored::Colorize; use tar::{self, Archive}; use super::decompressor::{DecompressionResult, Decompressor}; -use crate::{dialogs::Confirmation, file::File, utils}; +use crate::{dialogs::Confirmation, file::File, bytes::Bytes, utils}; #[derive(Debug)] pub struct TarDecompressor {} @@ -45,10 +45,10 @@ impl TarDecompressor { file.unpack_in(into)?; println!( - "{}: {:?} extracted. ({} bytes)", + "{}: {:?} extracted. ({})", "info".yellow(), into.join(file.path()?), - file.size() + Bytes::new(file.size()) ); let file_path = fs::canonicalize(file_path)?; diff --git a/src/decompressors/to_memory.rs b/src/decompressors/to_memory.rs index 810a29c33..aa82daf04 100644 --- a/src/decompressors/to_memory.rs +++ b/src/decompressors/to_memory.rs @@ -7,7 +7,7 @@ use colored::Colorize; use super::decompressor::{DecompressionResult, Decompressor}; use crate::utils; -// use niffler; +use crate::bytes::Bytes; use crate::{extension::CompressionFormat, file::File}; struct DecompressorToMemory {} @@ -37,10 +37,10 @@ impl DecompressorToMemory { let bytes_read = reader.read_to_end(&mut buffer)?; println!( - "{}: {:?} extracted into memory ({} bytes).", + "{}: {:?} extracted into memory ({}).", "info".yellow(), path, - bytes_read + Bytes::new(bytes_read as u64) ); Ok(buffer) diff --git a/src/decompressors/zip.rs b/src/decompressors/zip.rs index 48971a86c..7cfabf2b5 100644 --- a/src/decompressors/zip.rs +++ b/src/decompressors/zip.rs @@ -8,7 +8,7 @@ use colored::Colorize; use zip::{self, read::ZipFile, ZipArchive}; use super::decompressor::{DecompressionResult, Decompressor}; -use crate::{dialogs::Confirmation, file::File, utils}; +use crate::{dialogs::Confirmation, file::File, bytes::Bytes, utils}; #[cfg(unix)] fn __unix_set_permissions(file_path: &Path, file: &ZipFile) { @@ -73,10 +73,10 @@ impl ZipDecompressor { } } println!( - "{}: \"{}\" extracted. ({} bytes)", + "{}: \"{}\" extracted. ({})", "info".yellow(), file_path.display(), - file.size() + Bytes::new(file.size()) ); let mut output_file = fs::File::create(&file_path)?; diff --git a/src/evaluator.rs b/src/evaluator.rs index 8d01625a8..9d68f5d54 100644 --- a/src/evaluator.rs +++ b/src/evaluator.rs @@ -7,6 +7,7 @@ use std::{ use colored::Colorize; use crate::{ + bytes::Bytes, cli::{VERSION, Command}, compressors::{ Entry, Compressor, BzipCompressor, GzipCompressor, LzmaCompressor, TarCompressor, @@ -199,10 +200,10 @@ impl Evaluator { }; println!( - "{}: writing to {:?}. ({} bytes)", + "{}: writing to {:?}. ({})", "info".yellow(), output_path, - bytes.len() + Bytes::new(bytes.len() as u64) ); fs::write(output_path, bytes)?; diff --git a/src/extension.rs b/src/extension.rs index bb23dc830..f8a402984 100644 --- a/src/extension.rs +++ b/src/extension.rs @@ -7,7 +7,7 @@ use std::{ use CompressionFormat::*; -use crate::{debug, utils::to_utf}; +use crate::utils::to_utf; /// Represents the extension of a file, but only really caring about /// compression formats (and .tar). diff --git a/src/main.rs b/src/main.rs index e70b49918..f19879d01 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +mod bytes; mod cli; mod compressors; mod decompressors; diff --git a/src/test.rs b/src/test.rs index ebc32f8d7..3fc50651a 100644 --- a/src/test.rs +++ b/src/test.rs @@ -26,7 +26,7 @@ where } #[cfg(test)] -mod tests { +mod argparsing { use super::{make_dummy_files}; use crate::cli; use crate::cli::Command; @@ -103,6 +103,77 @@ mod tests { } } +#[cfg(test)] +mod byte_pretty_printing { + use crate::bytes::Bytes; + #[test] + fn bytes () { + assert_eq!( + &format!("{}", Bytes::new(234)), + "234.00 B" + ); + + assert_eq!( + &format!("{}", Bytes::new(999)), + "999.00 B" + ); + } + + #[test] + fn kilobytes () { + assert_eq!( + &format!("{}", Bytes::new(2234)), + "2.23 kB" + ); + + assert_eq!( + &format!("{}", Bytes::new(62500)), + "62.50 kB" + ); + + assert_eq!( + &format!("{}", Bytes::new(329990)), + "329.99 kB" + ); + } + + #[test] + fn megabytes () { + assert_eq!( + &format!("{}", Bytes::new(2750000)), + "2.75 MB" + ); + + assert_eq!( + &format!("{}", Bytes::new(55000000)), + "55.00 MB" + ); + + assert_eq!( + &format!("{}", Bytes::new(987654321)), + "987.65 MB" + ); + } + + #[test] + fn gigabytes () { + assert_eq!( + &format!("{}", Bytes::new(5280000000)), + "5.28 GB" + ); + + assert_eq!( + &format!("{}", Bytes::new(95200000000)), + "95.20 GB" + ); + + assert_eq!( + &format!("{}", Bytes::new(302000000000)), + "302.00 GB" + ); + } +} + // #[cfg(test)] // mod cli { // use super::*;