prebuilt-down 0.1.3

A CLI tool for resolve prebuilt binary dependencies
use anyhow::{Context, Result};
use reqwest::blocking::Client as ReqwestClient;
use reqwest::redirect::Policy as ReqwestRedirectPolicy;
use std::fs::File;
use std::io;
use std::path::PathBuf;
use std::sync::Arc;

use crate::core::cache::CacheManager;
use crate::traits::response_ext::ResponseExt;

const REDIRECT_LIMIT: usize = 10;

fn build_client() -> Result<ReqwestClient> {
    let client = ReqwestClient::builder()
        .redirect(ReqwestRedirectPolicy::limited(REDIRECT_LIMIT))
        .build()
        .context("failed to build http client")?;
    return Ok(client);
}

pub struct DownloadManager {
    cache: Arc<CacheManager>,
    client: ReqwestClient,
}

impl DownloadManager {
    pub fn init(cache: Arc<CacheManager>) -> Result<Arc<Self>> {
        let client = build_client()?;
        return Ok(Arc::new(Self { cache, client }));
    }

    pub fn download(&self, url: &str, fallback_filename: &str) -> Result<PathBuf> {
        let mut response = self.client.get(url).send()?.error_for_status()?;

        let filename = response.resolve_filename(fallback_filename);
        let download_path = self.cache.path_for(&filename);
        let mut file = File::create(&download_path)?;
        io::copy(&mut response, &mut file)?;
        return Ok(download_path);
    }
}