diff --git a/Cargo.toml b/Cargo.toml index d83769e..aa98c99 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,6 +76,7 @@ signal-hook = "0.1.8" [dev-dependencies] rand = "0.6.5" pretty-bytes = "0.2.2" +atty = "0.2.11" [features] blt-backend = ["bear-lib-terminal"] diff --git a/examples/vpv.rs b/examples/vpv.rs index 1c69a65..7c6d521 100644 --- a/examples/vpv.rs +++ b/examples/vpv.rs @@ -1,6 +1,3 @@ -extern crate cursive; -extern crate pretty_bytes; - use std::io; use cursive::traits::{Boxable, With}; @@ -25,7 +22,7 @@ fn main() { let start = time::Instant::now(); // If an argument is given, it is the file we'll read from. - // Else, read from stdin. + // Otherwise, read from stdin. let (source, len) = match std::env::args().nth(1) { Some(source) => { let meta = std::fs::metadata(&source).unwrap(); @@ -36,99 +33,113 @@ fn main() { None => (None, None), }; - // Start the copy in a separate thread - thread::spawn(move || { - // Copy to stdout - lock it for better performance. - let stdout = io::stdout(); - let mut stdout = stdout.lock(); - - match source { - None => { - // Copy from stdin - lock it for better performance. - let stdin = io::stdin(); - let stdin = stdin.lock(); - let mut reader = - utils::ProgressReader::new(counter_copy, stdin); - - // And copy! - io::copy(&mut reader, &mut stdout).unwrap(); - } - Some(source) => { - // Copy from stdin - lock it for better performance. - let input = std::fs::File::open(source).unwrap(); - let mut reader = - utils::ProgressReader::new(counter_copy, input); - - // And copy! - io::copy(&mut reader, &mut stdout).unwrap(); - } - } - - // When we're done, shut down the application - cb_sink.send(Box::new(|s: &mut Cursive| s.quit())).unwrap(); - }); - // Add a single view: progress status siv.add_layer( - Dialog::new().title("Copying...").content( - LinearLayout::vertical() - .child( - Canvas::new(counter.clone()) - .with_draw(move |c, printer| { - let ticks = c.get() as f64; - let now = time::Instant::now(); - let duration = now - start; + Dialog::new() + .title("Copying...") + .content( + LinearLayout::vertical() + .child( + Canvas::new(counter.clone()) + .with_draw(move |c, printer| { + let ticks = c.get() as f64; + let now = time::Instant::now(); + let duration = now - start; - let seconds = duration.as_secs() as f64 - + duration.subsec_nanos() as f64 * 1e-9; + let seconds = duration.as_secs() as f64 + + duration.subsec_nanos() as f64 * 1e-9; - let speed = ticks / seconds; + let speed = ticks / seconds; - // Print ETA if we have a file size - // Otherwise prints elapsed time. - if let Some(len) = len { - let remaining = (len as f64 - ticks) / speed; + // Print ETA if we have a file size + // Otherwise prints elapsed time. + if let Some(len) = len { + let remaining = + (len as f64 - ticks) / speed; + printer.print( + (0, 0), + &format!( + "ETA: {:.1} seconds", + remaining + ), + ); + } else { + printer.print( + (0, 0), + &format!( + "Elapsed: {:.1} seconds", + seconds + ), + ); + } printer.print( - (0, 0), - &format!( - "ETA: {:.1} seconds", - remaining - ), + (0, 1), + &format!("Copied: {}", convert(ticks)), ); - } else { printer.print( - (0, 0), - &format!( - "Elapsed: {:.1} seconds", - seconds - ), + (0, 2), + &format!("Speed: {}/s", convert(speed)), ); - } - printer.print( - (0, 1), - &format!("Copied: {}", convert(ticks)), + }) + .fixed_size((25, 3)), + ) + .with(|l| { + // If we have a file length, add a progress bar + if let Some(len) = len { + l.add_child( + ProgressBar::new() + .max(len as usize) + .with_value(counter.clone()), ); - printer.print( - (0, 2), - &format!("Speed: {}/s", convert(speed)), - ); - }) - .fixed_size((25, 3)), - ) - .with(|l| { - // If we have a file length, add a progress bar - if let Some(len) = len { - l.add_child( - ProgressBar::new() - .max(len as usize) - .with_value(counter.clone()), - ); - } - }), - ), + } + }), + ) + .button("Abort", Cursive::quit), ); - siv.set_autorefresh(true); + if source.is_none() && atty::is(atty::Stream::Stdin) { + siv.add_layer( + Dialog::text( + "Please specify an input file or redirect a file to stdin. + +cargo run --example vpv /dev/null", + ) + .button("Quit", Cursive::quit), + ); + } else { + // Start the copy in a separate thread + thread::spawn(move || { + // Copy to stdout - lock it for better performance. + let stdout = io::stdout(); + let mut stdout = stdout.lock(); + + match source { + None => { + // Copy from stdin - lock it for better performance. + let stdin = io::stdin(); + let stdin = stdin.lock(); + let mut reader = + utils::ProgressReader::new(counter_copy, stdin); + + // And copy! + io::copy(&mut reader, &mut stdout).unwrap(); + } + Some(source) => { + // Copy from stdin - lock it for better performance. + let input = std::fs::File::open(source).unwrap(); + let mut reader = + utils::ProgressReader::new(counter_copy, input); + + // And copy! + io::copy(&mut reader, &mut stdout).unwrap(); + } + } + + // When we're done, shut down the application + cb_sink.send(Box::new(|s: &mut Cursive| s.quit())).unwrap(); + }); + siv.set_autorefresh(true); + } siv.run(); }