From 57f49387a37ece7f5d270f66235df2bccef9eb9b Mon Sep 17 00:00:00 2001 From: Alexey Zinchenko Date: Mon, 22 Feb 2021 23:38:04 +0300 Subject: [PATCH] Added draft progress bar. --- Cargo.lock | 71 +++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/lib.rs | 33 ++++++++++++++++++----- tests/common.rs | 8 ------ 4 files changed, 98 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b0d2ee1..1f098b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -47,6 +47,27 @@ dependencies = [ "vec_map", ] +[[package]] +name = "console" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cc80946b3480f421c2f17ed1cb841753a371c7c5104f51d507e13f532c856aa" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "regex", + "terminal_size", + "unicode-width", + "winapi", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + [[package]] name = "getrandom" version = "0.2.2" @@ -67,6 +88,24 @@ dependencies = [ "libc", ] +[[package]] +name = "indicatif" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7baab56125e25686df467fe470785512329883aab42696d661247aca2a2896e4" +dependencies = [ + "console", + "lazy_static", + "number_prefix", + "regex", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" version = "0.2.82" @@ -114,6 +153,12 @@ dependencies = [ "syn", ] +[[package]] +name = "number_prefix" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b02fc0ff9a9e4b35b3342880f48e896ebf69f2967921fe8646bf5b7125956a" + [[package]] name = "ppv-lite86" version = "0.2.10" @@ -187,11 +232,27 @@ dependencies = [ "rand_core", ] +[[package]] +name = "regex" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" + [[package]] name = "rshred" version = "0.1.0" dependencies = [ "clap", + "indicatif", "ntest", "rand", "walkdir", @@ -229,6 +290,16 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "terminal_size" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ca8ced750734db02076f44132d802af0b33b09942331f4459dde8636fd2406" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "textwrap" version = "0.11.0" diff --git a/Cargo.toml b/Cargo.toml index 5f5fc24..ee9daaa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ license-file = "LICENSE" clap = "2.33.3" rand = "0.8.3" walkdir = "2.3.1" +indicatif = "0.15.0" [dev-dependencies] ntest = "0.7.3" diff --git a/src/lib.rs b/src/lib.rs index fba7dfe..d841dde 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,7 @@ use std::io; use std::process::exit; use walkdir::WalkDir; +use indicatif::{ProgressBar, ProgressStyle}; const BATCH_SIZE: usize = 8192; @@ -40,7 +41,7 @@ impl Shredder { exit(1); } } - if *verbosity > Verbosity::None { + if *verbosity > Verbosity::Low { println!("Using input file: {}", &self.options.raw_path); } @@ -54,17 +55,17 @@ impl Shredder { } } - fn shred_file(options: &ShredOptions, path: &str) { + fn shred_file(options: &ShredOptions, path: &str) -> bool { if options.verbosity > Verbosity::Low { println!("Trying to shred {}", path); } - match std::fs::canonicalize(path) { + return match std::fs::canonicalize(path) { Ok(path) => { let file_length = path.metadata().unwrap().len(); let absolute_path = path.to_str().unwrap(); if options.is_interactive { if !Shredder::user_prompt(absolute_path) { - return; + return false; } } @@ -75,9 +76,17 @@ impl Shredder { } let mut buffer = BufWriter::new(&file); - for _ in 0..options.rewrite_iterations { + println!("{}", absolute_path); + for iteration in 0..options.rewrite_iterations { let mut bytes_processed = 0; + let pb = ProgressBar::new(file_length); + pb.set_prefix(&format!("Iteration #{}", iteration + 1)); + pb.set_message(absolute_path); + pb.set_style(ProgressStyle::default_bar() + .template("{prefix} {spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {bytes}/{total_bytes} {bytes_per_sec} ({eta})") + .progress_chars("#>-")); + while bytes_processed < file_length { let bytes_to_write = if file_length - bytes_processed > BATCH_SIZE as u64 { BATCH_SIZE @@ -91,7 +100,10 @@ impl Shredder { buffer.write(&random_bytes).unwrap(); bytes_processed = bytes_processed + bytes_to_write as u64; + + pb.set_position(bytes_processed); } + pb.finish_with_message("shredded"); buffer.flush().unwrap(); file.sync_all().unwrap(); @@ -101,14 +113,20 @@ impl Shredder { if !options.keep_files { fs::remove_file(absolute_path).unwrap(); } + if options.verbosity > Verbosity::None { + println!("File '{}' shredded!", absolute_path); + } + true } Err(error) => { println!("{}", error); + false } } } Err(error) => { println!("{}", error); + false } } } @@ -117,8 +135,9 @@ impl Shredder { let mut files_count = 0; for entry in WalkDir::new(dir).into_iter().filter_map(|e| e.ok()) { if entry.metadata().unwrap().is_file() { - Shredder::shred_file(options, entry.path().to_str().unwrap()); - files_count = files_count + 1; + if Shredder::shred_file(options, entry.path().to_str().unwrap()) { + files_count = files_count + 1; + } } } if options.verbosity != Verbosity::None { diff --git a/tests/common.rs b/tests/common.rs index ae597d3..41c9cbe 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -25,13 +25,6 @@ pub fn setup(data_type: TestDataType) -> EnvironmentDetails { EnvironmentDetails::single(tmp_file_path) } - TestDataType::SingleFile(filename) => { - let tmp_file_path = format!("{}/{}", TEST_DIR, filename); - - prepare_file(&tmp_file_path); - - EnvironmentDetails::single(tmp_file_path) - } TestDataType::MultipleFiles(files) => { let files = files.iter().map(|file| format!("{}/{}", TEST_DIR, file)).collect::>(); for file in files.iter() { @@ -98,6 +91,5 @@ impl EnvironmentDetails { pub enum TestDataType { RandomSingleFile, - SingleFile(String), MultipleFiles(Vec), } \ No newline at end of file