use std::future::Future;
use std::pin::Pin;
use thiserror::Error;
use crate::models::{ReleaseInfo, RepoSort, RepositorySearchResult, TagPin};
#[derive(Debug, Error)]
pub enum ForgeError {
#[error("http error: {0}")]
Http(#[from] reqwest::Error),
#[error("timeout")]
Timeout,
#[error("rate limited")]
RateLimited,
#[error("parse error: {0}")]
Parse(String),
#[error("not supported")]
NotSupported,
}
pub type ForgeResult<T> = Result<T, ForgeError>;
pub trait Forge: Send + Sync {
fn id(&self) -> &str;
fn display_name(&self) -> &str;
fn supports_releases(&self) -> bool {
false
}
fn list_releases<'a>(
&'a self,
_owner: &'a str,
_repo: &'a str,
_limit: usize,
) -> Pin<Box<dyn Future<Output = ForgeResult<Vec<ReleaseInfo>>> + Send + 'a>> {
Box::pin(async { Err(ForgeError::NotSupported) })
}
fn resolve_tag<'a>(
&'a self,
_owner: &'a str,
_repo: &'a str,
_tag: &'a str,
) -> Pin<Box<dyn Future<Output = ForgeResult<TagPin>> + Send + 'a>> {
Box::pin(async { Err(ForgeError::NotSupported) })
}
fn supports_search(&self) -> bool {
false
}
fn search_repositories<'a>(
&'a self,
_query: &'a str,
_sort: RepoSort,
_language: Option<&'a str>,
_limit: usize,
) -> Pin<Box<dyn Future<Output = ForgeResult<Vec<RepositorySearchResult>>> + Send + 'a>> {
Box::pin(async { Err(ForgeError::NotSupported) })
}
}