1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
//! A simple command line utility that downloads a file into the void. It
//! demonstrates how the metrics API can be used to implement an interactive
//! progress bar.
//!
//! Command line options are parsed with [structopt] and the progress bar itself
//! rendered with [indicatif], both excellent libraries for writing command line
//! programs!
//!
//! [indicatif]: https://github.com/mitsuhiko/indicatif
//! [structopt]: https://github.com/TeXitoi/structopt
use indicatif::{FormattedDuration, HumanBytes, ProgressBar, ProgressStyle};
use isahc::{prelude::*, Request};
use std::io::Read;
use structopt::StructOpt;
#[derive(Debug, StructOpt)]
struct Options {
url: http::Uri,
}
fn main() -> Result<(), isahc::Error> {
let options = Options::from_args();
let bar = ProgressBar::new(0).with_style(
ProgressStyle::default_bar()
.template("{bar:40.cyan/blue} {bytes:>7}/{total_bytes:7} {msg}"),
);
let mut response = Request::get(options.url).metrics(true).body(())?.send()?;
let metrics = response.metrics().unwrap().clone();
let body = response.body_mut();
let mut buf = [0; 16384 * 4];
loop {
match body.read(&mut buf) {
Ok(0) => {
bar.finish();
break;
}
Ok(_) => {
bar.set_position(metrics.download_progress().0);
bar.set_length(metrics.download_progress().1);
bar.set_message(&format!(
"time: {} speed: {}/sec",
FormattedDuration(metrics.total_time()),
HumanBytes(metrics.download_speed() as u64),
));
}
Err(e) => {
bar.finish_at_current_pos();
eprintln!("Error: {}", e);
return Ok(());
}
}
}
Ok(())
}
|