use std::borrow::Cow;
#[cfg(test)]
use std::collections::BTreeMap;
use std::time::Duration;
use anyhow::{Result, bail};
use reqwest::Client;
use crate::cli::upgrade::ROOT;
pub(crate) trait VersionClient {
async fn fetch(&self, version: &str) -> Result<Cow<'static, str>>;
}
pub(crate) struct ReqwestVersionClient {
client: Client,
}
pub(crate) fn new(timeout: Option<Duration>) -> Result<ReqwestVersionClient> {
let mut client = Client::builder();
if let Some(timeout) = timeout {
client = client.timeout(timeout);
}
let client = client.build()?;
Ok(ReqwestVersionClient {
client,
})
}
impl VersionClient for ReqwestVersionClient {
async fn fetch(&self, version: &str) -> Result<Cow<'static, str>> {
let request = self.client.get(format!("{ROOT}/{version}.txt")).build()?;
let response = self.client.execute(request).await?;
if !response.status().is_success() {
bail!("received status {} when fetchin version", response.status())
}
Ok(Cow::Owned(response.text().await?.trim().to_owned()))
}
}
#[cfg(test)]
pub(crate) struct MapVersionClient {
pub(crate) fetch_mock: BTreeMap<String, fn() -> Result<String>>,
}
#[cfg(test)]
impl VersionClient for MapVersionClient {
async fn fetch(&self, version: &str) -> Result<Cow<'static, str>> {
let found = self.fetch_mock[version];
found().map(Cow::Owned)
}
}