diff --git a/src/bin/zstd.rs b/src/bin/zstd.rs index 9e59360..d6aebb7 100644 --- a/src/bin/zstd.rs +++ b/src/bin/zstd.rs @@ -5,6 +5,7 @@ use std::io::Read; use std::io::Seek; use std::io::SeekFrom; use std::io::Write; +use std::time::Instant; use ruzstd::encoding::CompressionLevel; use ruzstd::encoding::FrameCompressor; @@ -127,6 +128,27 @@ fn decompress(flags: &[String], file_paths: &[String]) { } } +struct PercentPrintReader { + total: usize, + counter: usize, + last_percent: usize, + reader: R, +} + +impl Read for PercentPrintReader { + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + let new_bytes = self.reader.read(buf)?; + self.counter += new_bytes; + let progress = self.counter * 100 / self.total; + if progress > self.last_percent { + self.last_percent = progress; + eprint!("\r"); + eprint!("{} % done", progress); + } + Ok(new_bytes) + } +} + fn main() { let mut file_paths: Vec<_> = std::env::args().filter(|f| !f.starts_with('-')).collect(); let flags: Vec<_> = std::env::args().filter(|f| f.starts_with('-')).collect(); @@ -134,21 +156,28 @@ fn main() { if flags.is_empty() { for path in file_paths { + let start_instant = Instant::now(); let file = std::fs::File::open(&path).unwrap(); let input_len = file.metadata().unwrap().len() as usize; - let file = BufReader::new(file); + let file = PercentPrintReader { + reader: BufReader::new(file), + total: input_len, + counter: 0, + last_percent: 0, + }; let mut output = Vec::new(); let mut encoder = FrameCompressor::new(file, &mut output, CompressionLevel::Fastest); encoder.compress(); println!( - "Compressed {path:} from {} to {} ({}%)", + "Compressed {path:} from {} to {} ({}%) took {}ms", input_len, output.len(), if input_len == 0 { 0 } else { output.len() * 100 / input_len - } + }, + start_instant.elapsed().as_millis() ); } } else {