use async_trait::async_trait;
use thiserror::Error;
use crate::types::Repo;
#[derive(Debug, Error)]
pub enum ForgeError {
#[error("Repository not found: {name}")]
RepoNotFound { name: String },
#[error("Repository already exists: {name}")]
RepoAlreadyExists { name: String },
#[error("Authentication failed: {message}")]
AuthenticationFailed { message: String },
#[error("Network error: {0}")]
NetworkError(String),
#[error("API error: {0}")]
ApiError(String),
#[error("I/O error: {0}")]
IoError(#[from] std::io::Error),
#[error("Serialization error: {0}")]
SerdeError(String),
}
pub type ForgeResult<T> = std::result::Result<T, ForgeError>;
#[async_trait]
pub trait ForgePort: Send + Sync {
async fn list_repos(&self, org: &str) -> ForgeResult<Vec<Repo>>;
async fn get_repo(&self, org: &str, name: &str) -> ForgeResult<Repo>;
async fn create_repo(&self, org: &str, repo: &Repo) -> ForgeResult<()>;
async fn update_repo(&self, org: &str, repo: &Repo) -> ForgeResult<()>;
async fn delete_repo(&self, org: &str, name: &str) -> ForgeResult<()>;
async fn rename_repo(&self, org: &str, old_name: &str, new_name: &str) -> ForgeResult<()>;
async fn repo_exists(&self, org: &str, name: &str) -> ForgeResult<bool> {
match self.get_repo(org, name).await {
Ok(_) => Ok(true),
Err(ForgeError::RepoNotFound { .. }) => Ok(false),
Err(e) => Err(e),
}
}
}