135 lines
4.1 KiB
Rust
135 lines
4.1 KiB
Rust
//! 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<ExtensionType>,
|
|
) -> Result<Vec<Extension>>;
|
|
|
|
/// Get specific extension metadata
|
|
async fn get_extension(&self, extension_type: ExtensionType, name: &str) -> Result<Extension>;
|
|
|
|
/// List all versions for an extension
|
|
async fn list_versions(
|
|
&self,
|
|
extension_type: ExtensionType,
|
|
name: &str,
|
|
) -> Result<Vec<ExtensionVersion>>;
|
|
|
|
/// Download extension artifact
|
|
async fn download_extension(
|
|
&self,
|
|
extension_type: ExtensionType,
|
|
name: &str,
|
|
version: &str,
|
|
) -> Result<Bytes>;
|
|
|
|
/// 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<String>;
|
|
|
|
/// List all releases for a repository
|
|
///
|
|
/// Returns release info including tags, assets, and creation times
|
|
async fn list_releases(&self, repo_name: &str) -> Result<Vec<ReleaseInfo>>;
|
|
|
|
/// Get release notes/description for a specific version
|
|
async fn get_release_notes(&self, repo_name: &str, version: &str) -> Result<String>;
|
|
}
|
|
|
|
/// 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<ManifestInfo>;
|
|
|
|
/// List all catalogs/repositories in the registry
|
|
async fn list_catalog(&self) -> Result<Vec<String>>;
|
|
|
|
/// Get digest for an artifact
|
|
async fn get_digest(&self, repo_name: &str, tag: &str) -> Result<String>;
|
|
|
|
/// Verify artifact integrity
|
|
async fn verify_artifact(&self, repo_name: &str, tag: &str, digest: &str) -> Result<bool>;
|
|
}
|
|
|
|
/// Release information from source backends
|
|
#[derive(Debug, Clone)]
|
|
pub struct ReleaseInfo {
|
|
pub tag: String,
|
|
pub created_at: chrono::DateTime<chrono::Utc>,
|
|
pub published_at: Option<chrono::DateTime<chrono::Utc>>,
|
|
pub assets: Vec<ReleaseAsset>,
|
|
pub description: String,
|
|
}
|
|
|
|
/// Asset attached to a release
|
|
#[derive(Debug, Clone)]
|
|
pub struct ReleaseAsset {
|
|
pub name: String,
|
|
pub download_url: String,
|
|
pub size: Option<u64>,
|
|
}
|
|
|
|
/// OCI manifest information
|
|
#[derive(Debug, Clone)]
|
|
pub struct ManifestInfo {
|
|
pub config_digest: String,
|
|
pub layers: Vec<LayerInfo>,
|
|
pub total_size: u64,
|
|
}
|
|
|
|
/// OCI layer information
|
|
#[derive(Debug, Clone)]
|
|
pub struct LayerInfo {
|
|
pub digest: String,
|
|
pub size: u64,
|
|
pub media_type: String,
|
|
}
|