use serde::Deserialize;
use crate::Result;
use crate::common::http::USER_AGENT;
use crate::common::urls::{RABBITMQ_SERVER_API_URL, SERVER_PACKAGES_API_URL};
use crate::errors::Error;
use crate::version::Version;
#[derive(Debug, Deserialize)]
pub struct GitHubRelease {
pub tag_name: String,
pub name: String,
pub published_at: String,
}
pub struct AlphaRelease {
pub version: Version,
pub tag: String,
pub published_at: String,
}
pub async fn find_server_packages_release_tag(
client: &reqwest::Client,
version: &Version,
) -> Result<String> {
let version_str = version.to_string();
let releases: Vec<GitHubRelease> = client
.get(SERVER_PACKAGES_API_URL)
.query(&[("per_page", "100")])
.header("User-Agent", USER_AGENT)
.send()
.await?
.json()
.await?;
for release in releases {
if release.name.contains(&version_str) {
return Ok(release.tag_name);
}
}
Err(Error::ReleaseNotFound(version_str))
}
pub async fn fetch_alpha_releases(client: &reqwest::Client) -> Result<Vec<AlphaRelease>> {
let releases: Vec<GitHubRelease> = client
.get(SERVER_PACKAGES_API_URL)
.query(&[("per_page", "100")])
.header("User-Agent", USER_AGENT)
.send()
.await?
.json()
.await?;
let mut alpha_releases = Vec::new();
for release in releases {
if let Some(version) = parse_version_from_release_name(&release.name)
&& version.is_distributed_via_server_packages_repository()
{
alpha_releases.push(AlphaRelease {
version,
tag: release.tag_name,
published_at: release.published_at,
});
}
}
Ok(alpha_releases)
}
pub async fn find_latest_alpha(client: &reqwest::Client) -> Result<AlphaRelease> {
let releases = fetch_alpha_releases(client).await?;
releases
.into_iter()
.max_by(|a, b| a.published_at.cmp(&b.published_at))
.ok_or(Error::NoAlphaReleasesFound)
}
pub fn parse_version_from_release_name(name: &str) -> Option<Version> {
let name = name.trim();
if let Some(rest) = name.strip_prefix("RabbitMQ ") {
let version_part = rest.split_whitespace().next()?;
version_part.parse().ok()
} else {
None
}
}
pub async fn find_latest_ga_release(client: &reqwest::Client) -> Result<Version> {
let releases: Vec<GitHubRelease> = client
.get(RABBITMQ_SERVER_API_URL)
.query(&[("per_page", "50")])
.header("User-Agent", USER_AGENT)
.send()
.await?
.json()
.await?;
for release in releases {
if let Some(version) = parse_version_from_tag(&release.tag_name)
&& version.is_ga()
{
return Ok(version);
}
}
Err(Error::ReleaseNotFound("no GA releases found".to_string()))
}
pub fn parse_version_from_tag(tag: &str) -> Option<Version> {
let version_str = tag.strip_prefix('v')?;
version_str.parse().ok()
}