1use reqwest::header::HeaderMap;
18
19use crate::error::{Error, Result};
20
21pub async fn fetch_content(
26 name: &str,
27 url: &str,
28 headers: Option<HeaderMap>,
29 show_progress: bool,
30) -> Result<Vec<u8>> {
31 let client = reqwest::Client::new();
32 let mut request = client.get(url);
33 if let Some(headers) = headers {
34 request = request.headers(headers);
35 }
36
37 let mut response = request.send().await.map_err(Error::RequestFailed)?;
38 let total_size = response.content_length().unwrap_or(0);
39 let mut content = Vec::new();
40
41 if !response.status().is_success() {
42 return Err(Error::HttpError(response.status()).into());
43 }
44
45 if show_progress {
46 let pb = indicatif::ProgressBar::new(total_size);
47 pb.set_style(indicatif::ProgressStyle::default_bar()
48 .template("{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {bytes}/{total_bytes} ({eta})")
49 .unwrap()
50 .progress_chars("#>-"));
51 pb.set_message(name.to_string());
52
53 while let Some(chunk) = response.chunk().await.map_err(Error::RequestFailed)? {
54 content.extend_from_slice(&chunk);
55 pb.inc(chunk.len() as u64);
56 }
57 pb.finish_with_message("Download complete");
58 } else {
59 content = response
60 .bytes()
61 .await
62 .map_err(Error::RequestFailed)?
63 .to_vec();
64 }
65
66 Ok(content)
67}