From 499d1ca1858ee7dc8709be0bf36a7276eada06cf Mon Sep 17 00:00:00 2001 From: Mike Lubinets Date: Wed, 26 Apr 2017 19:00:46 +0300 Subject: [PATCH] Beautiful status line with indicatif --- Cargo.lock | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 3 ++- src/main.rs | 55 +++++++++++++++++++------------------- 3 files changed, 104 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 06cbffb..b1f8ce4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,11 +1,12 @@ [root] name = "batch_resolve_cli" -version = "0.3.1" +version = "0.3.2" dependencies = [ "clap 2.21.2 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "indicatif 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -115,6 +116,17 @@ dependencies = [ "vec_map 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "clicolors-control" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crossbeam" version = "0.2.10" @@ -175,6 +187,21 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "indicatif" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "clicolors-control 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "iovec" version = "0.1.0" @@ -324,6 +351,36 @@ dependencies = [ "user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "owning_ref" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot_core" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "pkg-config" version = "0.3.9" @@ -407,6 +464,16 @@ name = "slab" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "smallvec" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "stable_deref_trait" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "strsim" version = "0.6.0" @@ -606,6 +673,7 @@ dependencies = [ "checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c" "checksum chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "9213f7cd7c27e95c2b57c49f0e69b1ea65b27138da84a170133fd21b07659c00" "checksum clap 2.21.2 (registry+https://github.com/rust-lang/crates.io-index)" = "58ad5e8142f3a5eab0c1cba5011aa383e009842936107fe4d94f1a8d380a1aec" +"checksum clicolors-control 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "61bd6bff2f99f947c2dbdc73cd0ebd55d8263b921fd4f68a44598555be49f32b" "checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97" "checksum data-encoding 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d867ddbf09de0b73e09ec798972fb7f870495a0893f6f736c1855448c5a56789" "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" @@ -615,6 +683,7 @@ dependencies = [ "checksum futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8e51e7f9c150ba7fd4cee9df8bf6ea3dea5b63b68955ddad19ccd35b71dcfb4d" "checksum gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)" = "40899336fb50db0c78710f53e87afc54d8c7266fb76262fecc78ca1a7f09deae" "checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518" +"checksum indicatif 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0f6831da41884fc283d436fc213892db0521e546afae0ec46d509f5ae0f6a4e8" "checksum iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7291b1dd97d331f752620b02dfdbc231df7fc01bf282a00769e1cdb963c460dc" @@ -632,6 +701,9 @@ dependencies = [ "checksum num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a18c392466409c50b87369414a2680c93e739aedeb498eb2bff7d7eb569744e2" "checksum openssl 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d59714233ccf23bc962f5eddc5d5c551c5848400e5ab01c64dded1743f3e3784" "checksum openssl-sys 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "376c5c6084e5ea95eea9c3280801e46d0dcf51251d4f01b747e044fb64d1fb31" +"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" +"checksum parking_lot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aebb68eebde2c99f89592d925288600fde220177e46b5c9a91ca218d245aeedf" +"checksum parking_lot_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "56a19dcbb5d1e32b6cccb8a9aa1fc2a38418c8699652e735e2bf391a3dc0aa16" "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d" @@ -645,6 +717,8 @@ dependencies = [ "checksum serde_codegen_internals 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d52006899f910528a10631e5b727973fe668f3228109d1707ccf5bad5490b6e" "checksum serde_derive 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f15ea24bd037b2d64646b4d934fa99c649be66e3f7b29fb595a5543b212b1452" "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" +"checksum smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4f8266519bc1d17d0b5b16f6c21295625d562841c708f6376f49028a43e9c11e" +"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b" "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" "checksum syn 0.11.9 (registry+https://github.com/rust-lang/crates.io-index)" = "480c834701caba3548aa991e54677281be3a5414a9d09ddbdf4ed74a569a9d19" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" diff --git a/Cargo.toml b/Cargo.toml index 0822729..d14a398 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "batch_resolve_cli" description = "Fast asynchronous batch DNS resolver built on top of Tokio and TRust-DNS" -version = "0.3.1" +version = "0.3.2" authors = ["Mike Lubinets "] homepage = "http://github.com/mersinvald/batch_resolve" repository = "http://github.com/mersinvald/batch_resolve" @@ -26,6 +26,7 @@ serde_derive = "0.9" toml = "0.3" crossbeam = "0.2" num_cpus = "1.3.0" +indicatif = "0.1.0" [dependencies.trust-dns] version = "0.10" diff --git a/src/main.rs b/src/main.rs index 80922ae..8bd1198 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,7 @@ extern crate trust_dns; extern crate tokio_core; extern crate crossbeam; extern crate num_cpus; +extern crate indicatif; #[macro_use] mod macros; @@ -24,19 +25,19 @@ use std::collections::{HashMap, HashSet}; use std::path::Path; use std::io::{self, Read, Write}; use std::fs::File; -use std::sync::mpsc; use std::thread; -use std::time::{Instant, Duration}; +use std::time::Duration; use std::sync::{Arc, Mutex}; use std::env; -use std::io::stdout; use clap::{Arg, App}; use log::{LogRecord, LogLevelFilter}; use env_logger::LogBuilder; +use indicatif::{ProgressBar, ProgressStyle}; + fn process_args() -> (Vec, Vec, Vec) { let app = App::new("Batch Resolve") .about("Fast asynchronous DNS batch resolver") @@ -196,36 +197,34 @@ fn main() { } // Create status output thread and register status callback - let (status_tx, status_rx) = mpsc::channel::(); - + let status = Arc::new(Mutex::new(Status::default())); + let status_clone = status.clone(); + thread::spawn(move || { + let pb = ProgressBar::new(overall_count as u64); + pb.set_style(ProgressStyle::default_bar() + .template("{spinner:.green} [{elapsed}] [{wide_bar:.cyan/blue}] {pos}/{len} ({eta}) | {msg} {spinner:.green}") + .progress_chars("#>-")); + // Print every 100ms - let mut instant = Instant::now(); - for status in status_rx.iter() { - if instant.elapsed() > Duration::from_millis(100) { - let running = format!("{:6} running", status.running); - let done = format!("{:6}/{} done", status.done, overall_count); - let success = format!("{:6}/{} succeded", status.success, overall_count); - let fail = format!("{:6}/{} failed", status.fail, overall_count); - let error = format!("{:6} errored", status.errored); - - print!("{} {} {} {} {}\r", - running, - done, - success, - fail, - error - ); - - stdout().flush().unwrap(); - - instant = Instant::now(); - } + let mut status; + + while { + status = status_clone.lock().unwrap().clone(); + status.done < overall_count as u64 + } { + let message = format!("{} running | {} failed", status.running, status.fail); + pb.set_position(status.done); + pb.set_message(&message); + thread::sleep(Duration::from_millis(30)); } + + pb.finish_with_message("done"); }); - batch.register_status_callback(Box::new(move |status: Status| { - status_tx.send(status).unwrap(); + + batch.register_status_callback(Box::new(move |s: Status| { + *status.lock().unwrap() = s; })); // Execute batch job