use std::sync::mpsc;
use std::time::Duration;
use super::parse;
use super::status::ReleaseInfo;
use crate::app::AppEvent;
pub(crate) const GITHUB_URL: &str = "https://github.com/mijowi/edamame";
const RELEASES_API_URL: &str = "https://api.github.com/repos/mijowi/edamame/releases/latest";
const FETCH_TIMEOUT: Duration = Duration::from_secs(10);
const BODY_CAP_BYTES: u64 = 256 * 1024;
pub(crate) fn release_url(tag: &str) -> String {
format!("{GITHUB_URL}/releases/tag/{tag}")
}
pub(crate) fn spawn_release_check(tx: mpsc::Sender<AppEvent>) {
std::thread::spawn(move || {
let result = fetch_release(RELEASES_API_URL);
let _ = tx.send(AppEvent::ReleaseCheckResult(result));
});
}
fn fetch_release(url: &str) -> Result<ReleaseInfo, String> {
let agent: ureq::Agent = ureq::Agent::config_builder()
.timeout_connect(Some(FETCH_TIMEOUT))
.timeout_recv_response(Some(FETCH_TIMEOUT))
.timeout_recv_body(Some(FETCH_TIMEOUT))
.build()
.into();
let mut response = agent
.get(url)
.header("User-Agent", concat!("edamame/", env!("CARGO_PKG_VERSION")))
.call()
.map_err(|e| e.to_string())?;
let bytes = response
.body_mut()
.with_config()
.limit(BODY_CAP_BYTES)
.read_to_vec()
.map_err(|e| e.to_string())?;
let body = String::from_utf8_lossy(&bytes);
parse::parse_release(&body).ok_or_else(|| "no tag_name in release response".to_owned())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn release_url_names_the_tag() {
assert_eq!(
release_url("v0.2.0"),
"https://github.com/mijowi/edamame/releases/tag/v0.2.0"
);
}
}