use crate::context::check_http_response_success;
use crate::log::{log_action, log_warn_action, LogColorize};
use anyhow::{anyhow, Context};
use std::path::PathBuf;
use url::Url;
pub struct RemoteComponents {
client: reqwest::Client,
temp_dir: PathBuf,
offline: bool,
}
impl RemoteComponents {
pub fn new(client: reqwest::Client, target: PathBuf, offline: bool) -> Self {
Self {
client,
temp_dir: target,
offline,
}
}
pub async fn get_from_url(&self, url: &Url) -> anyhow::Result<PathBuf> {
let parent_dir = self.temp_dir.join("remote-components");
crate::fs::create_dir_all(&parent_dir)?;
let url_hash = blake3::hash(url.as_str().as_bytes()).to_hex();
let path = parent_dir.join(format!("{url_hash}.wasm"));
if std::fs::exists(&path)? {
log_warn_action(
"Skipping",
format!(
"download of remote WASM component: {}, using a previously downloaded version",
url.as_str().log_color_highlight()
),
);
Ok(path)
} else if !self.offline {
log_action(
"Downloading",
format!(
"remote WASM component: {}",
url.as_str().log_color_highlight()
),
);
let response =
self.client.get(url.clone()).send().await.with_context(|| {
anyhow!("Failed to download remote component WASM: {}", url)
})?;
let response = check_http_response_success(response).await?;
let bytes = response
.bytes()
.await
.with_context(|| anyhow!("Failed to download remote component WASM: {}", url))?;
std::fs::write(&path, bytes)?;
Ok(path)
} else {
Err(anyhow!(
"Offline mode is enabled, but the remote component '{}' is not downloaded yet",
url
))
}
}
}