//! Client trait hierarchy for extension sources and distributions //! //! Defines three-tier trait system: //! - `ExtensionClient`: Base trait for all backends //! - `SourceClient`: Git-based repository sources (Gitea, Forgejo, GitHub) //! - `DistributionClient`: OCI-compatible registries (Harbor, Docker Hub, etc.) use async_trait::async_trait; use bytes::Bytes; use crate::error::Result; use crate::models::{Extension, ExtensionType, ExtensionVersion}; /// Backend type identifier #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BackendType { Gitea, Forgejo, GitHub, Oci, } /// Base trait for all extension clients /// /// Common operations that all backends must support, regardless of whether /// they're source (Git) or distribution (OCI) backends. #[async_trait] pub trait ExtensionClient: Send + Sync { /// Get unique backend identifier for this instance fn backend_id(&self) -> &str; /// Get backend type fn backend_type(&self) -> BackendType; /// List all extensions available from this backend async fn list_extensions( &self, extension_type: Option, ) -> Result>; /// Get specific extension metadata async fn get_extension(&self, extension_type: ExtensionType, name: &str) -> Result; /// List all versions for an extension async fn list_versions( &self, extension_type: ExtensionType, name: &str, ) -> Result>; /// Download extension artifact async fn download_extension( &self, extension_type: ExtensionType, name: &str, version: &str, ) -> Result; /// Check backend health async fn health_check(&self) -> Result<()>; } /// Source client trait for Git-based backends /// /// Extends `ExtensionClient` with operations specific to Git repository sources /// like Gitea, Forgejo, and GitHub. These backends treat extensions as releases /// in repositories. #[async_trait] pub trait SourceClient: ExtensionClient { /// Get repository URL for an extension async fn get_repository_url(&self, extension_type: ExtensionType, name: &str) -> Result; /// List all releases for a repository /// /// Returns release info including tags, assets, and creation times async fn list_releases(&self, repo_name: &str) -> Result>; /// Get release notes/description for a specific version async fn get_release_notes(&self, repo_name: &str, version: &str) -> Result; } /// Distribution client trait for OCI registries /// /// Extends `ExtensionClient` with operations specific to OCI registries /// like Docker Hub, Harbor, Quay, and ghcr.io. These backends treat extensions /// as container images or artifacts with OCI manifests. #[async_trait] pub trait DistributionClient: ExtensionClient { /// Get manifest for an artifact async fn get_manifest(&self, repo_name: &str, tag: &str) -> Result; /// List all catalogs/repositories in the registry async fn list_catalog(&self) -> Result>; /// Get digest for an artifact async fn get_digest(&self, repo_name: &str, tag: &str) -> Result; /// Verify artifact integrity async fn verify_artifact(&self, repo_name: &str, tag: &str, digest: &str) -> Result; } /// Release information from source backends #[derive(Debug, Clone)] pub struct ReleaseInfo { pub tag: String, pub created_at: chrono::DateTime, pub published_at: Option>, pub assets: Vec, pub description: String, } /// Asset attached to a release #[derive(Debug, Clone)] pub struct ReleaseAsset { pub name: String, pub download_url: String, pub size: Option, } /// OCI manifest information #[derive(Debug, Clone)] pub struct ManifestInfo { pub config_digest: String, pub layers: Vec, pub total_size: u64, } /// OCI layer information #[derive(Debug, Clone)] pub struct LayerInfo { pub digest: String, pub size: u64, pub media_type: String, }