use crate::USER_AGENT;
use crate::app_info::{WORKBENCH_DOWNLOADS_URL, WORKBENCH_LATEST_URL};
use crate::built_info;
use crate::download::download_binary;
use anyhow::{Context, Result};
use reqwest::Client;
use semver::Version;
use serde::Deserialize;
use std::path::Path;
pub struct WorkbenchApi {
client: Client,
}
impl WorkbenchApi {
pub fn new() -> Self {
Self {
client: Client::new(),
}
}
async fn latest_manifest(&mut self) -> Result<LatestManifest> {
let manifest = self
.client
.get(WORKBENCH_LATEST_URL)
.header(reqwest::header::USER_AGENT, USER_AGENT)
.send()
.await?
.error_for_status()?
.text()
.await?;
toml::from_str(&manifest).context("Failed to parse workbench latest manifest")
}
pub async fn latest_release(&mut self) -> Result<Release> {
let manifest = self.latest_manifest().await?;
Ok(Release {
version: manifest.version,
})
}
pub async fn download_binary(&mut self, url: &str, dest: &Path) -> Result<()> {
download_binary(&self.client, url, dest).await
}
}
#[derive(Debug, Deserialize)]
struct LatestManifest {
pub version: Version,
}
#[derive(Debug)]
pub struct Release {
pub version: Version,
}
impl Release {
pub fn get_asset_url(&self) -> String {
let asset_name = asset_name();
format!("{WORKBENCH_DOWNLOADS_URL}/{}/{}", self.version, asset_name)
}
}
fn asset_name() -> String {
let os = built_info::CFG_OS;
let arch = built_info::CFG_TARGET_ARCH;
let suffix = match (os, arch) {
("macos", "aarch64") => "macos-arm",
("macos", "x86_64") => "macos-intel",
("windows", "x86_64") => "windows-x64.exe",
("linux", "x86_64") => "linux-x64",
_ => "linux-x64",
};
format!("workbench-{suffix}")
}