pkgutils/
download.rs

1use std::fs::File;
2use std::io::{self, stderr, Read, Write};
3use std::time::Duration;
4
5use reqwest::{
6    blocking::Client,
7    StatusCode,
8};
9
10use pbr::{ProgressBar, Units};
11
12pub fn download_client() -> Client {
13    Client::builder()
14        .timeout(Duration::new(5, 0))
15        .build()
16        .unwrap()
17}
18
19pub fn download(client: &Client, remote_path: &str, local_path: &str) -> io::Result<()> {
20    let mut stderr = stderr();
21
22    write!(stderr, "* Requesting {}\n", remote_path)?;
23
24    let mut response = match client.get(remote_path).send() {
25        Ok(response) => response,
26        Err(err) => return Err(io::Error::new(io::ErrorKind::Other, err)),
27    };
28
29    match response.status() {
30        StatusCode::OK => {
31            let mut count = 0;
32            let length = response.content_length().unwrap_or(0);
33
34            let mut file = File::create(&local_path)?;
35            let mut pb = ProgressBar::new(length as u64);
36            pb.set_max_refresh_rate(Some(Duration::new(1, 0)));
37            pb.set_units(Units::Bytes);
38            loop {
39                let mut buf = [0; 8192];
40                let res = response.read(&mut buf)?;
41                if res == 0 {
42                    break;
43                }
44                count += file.write(&buf[..res])?;
45                pb.set(count as u64);
46            }
47            let _ = write!(stderr, "\n");
48
49            file.sync_all()?;
50
51            Ok(())
52        }
53        _ => {
54            let _ = write!(stderr, "* Failure {}\n", response.status());
55
56            Err(io::Error::new(
57                io::ErrorKind::NotFound,
58                format!("{} not found", remote_path),
59            ))
60        }
61    }
62}