60 lines
1.8 KiB
Rust
60 lines
1.8 KiB
Rust
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<Vec<u8>> {
|
|
// 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<String>) -> 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::<Vec<_>>()
|
|
.join("");
|
|
|
|
file.write_all(contents.as_bytes())?;
|
|
|
|
println!("Decklist saved to {}", filepath);
|
|
Ok(())
|
|
}
|