use super::azure::AzureReleaseClient;
use super::bitbucket::BitbucketReleaseClient;
use super::gitea::GiteaReleaseClient;
use super::github::GitHubReleaseClient;
use super::gitlab::GitLabReleaseClient;
use super::radicle::RadicleReleaseClient;
use super::sourcehut::SourcehutReleaseClient;
use crate::error::{Result, ToriiError};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Release {
pub tag: String,
pub name: String,
pub description: String,
pub created_at: String,
pub web_url: String,
pub id: Option<String>,
}
#[allow(dead_code)]
pub trait ReleaseClient: Send {
fn list(&self, owner: &str, repo: &str, limit: usize) -> Result<Vec<Release>>;
fn get(&self, owner: &str, repo: &str, tag: &str) -> Result<Release>;
fn edit(
&self,
owner: &str,
repo: &str,
tag: &str,
name: Option<&str>,
description: Option<&str>,
) -> Result<()>;
fn delete(&self, owner: &str, repo: &str, tag: &str) -> Result<()>;
}
pub fn get_release_client(platform: &str) -> Result<Box<dyn ReleaseClient>> {
match platform.to_lowercase().as_str() {
"github" => Ok(Box::new(GitHubReleaseClient::new()?)),
"gitlab" => Ok(Box::new(GitLabReleaseClient::new()?)),
"gitea" => Ok(Box::new(GiteaReleaseClient::new()?)),
"sourcehut" => Ok(Box::new(SourcehutReleaseClient::new()?)),
"radicle" => Ok(Box::new(RadicleReleaseClient::new()?)),
"bitbucket" => Ok(Box::new(BitbucketReleaseClient::new()?)),
"azure" => Ok(Box::new(AzureReleaseClient::new()?)),
other => Err(ToriiError::Unsupported(format!("Unsupported platform: {}. Supported: github, gitlab, gitea, sourcehut, radicle, bitbucket, azure", other))),
}
}
#[cfg(test)]
mod tests {
use crate::platforms::github::release::parse_github_release;
use crate::platforms::gitlab::release::parse_gitlab_release;
#[test]
fn parse_github_release_basic() {
let json = serde_json::json!({
"id": 12345u64,
"tag_name": "v0.7.9",
"name": "Gitorii v0.7.9",
"body": "Release notes here",
"created_at": "2026-05-19T22:00:00Z",
"html_url": "https://github.com/paskidev/gitorii/releases/tag/v0.7.9"
});
let r = parse_github_release(&json).unwrap();
assert_eq!(r.tag, "v0.7.9");
assert_eq!(r.name, "Gitorii v0.7.9");
assert_eq!(r.id.as_deref(), Some("12345"));
}
#[test]
fn parse_gitlab_release_basic() {
let json = serde_json::json!({
"tag_name": "v0.7.9",
"name": "Gitorii v0.7.9",
"description": "Release notes",
"created_at": "2026-05-19T22:00:00Z",
"_links": { "self": "https://gitlab.com/paskidev/gitorii/-/releases/v0.7.9" }
});
let r = parse_gitlab_release(&json).unwrap();
assert_eq!(r.tag, "v0.7.9");
assert_eq!(r.id, None);
assert_eq!(
r.web_url,
"https://gitlab.com/paskidev/gitorii/-/releases/v0.7.9"
);
}
}