use anyhow::{anyhow, Result}; use futures_util::StreamExt; use indicatif::{ProgressBar, ProgressStyle}; use reqwest::Client; use std::{cmp::min, fs::File, io::Write}; pub async fn open_or_download(url: &str, path: &str) -> Result> { // Download file if it doesn't exist if !tokio::fs::try_exists(path).await? { download_file(url, path).await?; } else { println!("{} found", path); } Ok(tokio::fs::read(path).await?) } async fn download_file(url: &str, path: &str) -> Result<()> { // Reqwest setup let res = Client::new().get(url).send().await?; let total_size = res.content_length().unwrap(); // Indicatif setup let pb = ProgressBar::new(total_size); pb.set_style(ProgressStyle::default_bar() .template("{msg}\n{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({bytes_per_sec}, {eta})")? .progress_chars("#>-")); pb.set_message(format!("Downloading {}", url)); let mut file = File::create(path)?; let mut downloaded: u64 = 0; let mut stream = res.bytes_stream(); while let Some(item) = stream.next().await { let chunk = item?; file.write_all(&chunk)?; let new = min(downloaded + (chunk.len() as u64), total_size); downloaded = new; pb.set_position(new); } pb.finish_with_message(format!("Downloaded {} to {}", url, path)); Ok(()) } pub async fn save_decklist(filepath: &str, decklist: Vec) -> Result<()> { let mut file = File::create(filepath).or(Err(anyhow!("Failed to create file '{}'", filepath)))?; let contents = decklist .iter() .map(|line| format!("1 {}\n", line)) .collect::>() .join(""); file.write_all(contents.as_bytes())?; println!("Decklist saved to {}", filepath); Ok(()) }