use std::sync::Arc;
use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use repository_file_rust::RustRepoFile as RustRepo;
use repository_znippy_rust::RustRepoZnippy;
use repository_znippy_maven::MavenRepoZnippy;
use repository_znippy_python::PipRepoZnippy;
use repository_znippy_npm::NpmRepoZnippy;
use repository_znippy_nuget::NugetRepoZnippy;
use repository_znippy_go::GoRepoZnippy;
use repository_znippy_gem::GemRepoZnippy;
use repository_znippy_deb::DebRepoZnippy;
use repository_znippy_rpm::RpmRepoZnippy;
use repository_znippy_helm::HelmRepoZnippy;
use repository_file_oci::OciRepoFile;
use repository_znippy_docker::DockerRepoZnippy;
use repository_znippy_conda::CondaRepoZnippy;
use repository_znippy_composer::ComposerRepoZnippy;
use repository_znippy_package::ZnippyRepoZnippy;
use traits::RepositoryBackendTrait;
use crate::{ExposedEndpoint, StorageEndpoint};
#[derive(Serialize, Deserialize)]
pub struct Repository {
pub ron_name: String,
pub ron_repo_type: String, pub ron_upstreams: Vec<String>, pub ron_in: Option<RepositoryIO>,
pub ron_out: Option<RepositoryIO>,
#[serde(default)]
pub ron_archive_path: Option<String>,
#[serde(default)]
pub ron_data_dir: Option<String>,
#[serde(default)]
pub ron_base_url: Option<String>,
#[serde(skip_serializing, skip_deserializing, default)]
pub backend_repository: Option<Arc<dyn RepositoryBackendTrait>>,
#[serde(skip_serializing, skip_deserializing, default)]
pub wired_upstreams: Vec<*const Repository>, }
impl Repository {
pub fn backend_from_config(&mut self) -> anyhow::Result<()> {
macro_rules! znippy_backed {
($ty:ty, $label:expr) => {{
if let Some(archive_path) = &self.ron_archive_path {
let repo = <$ty>::with_archive(
self.ron_name.clone(),
PathBuf::from(archive_path),
)?;
self.backend_repository = Some(Arc::new(repo));
} else {
anyhow::bail!(concat!($label, " repository requires ron_archive_path to a znippy archive"));
}
Ok(())
}};
}
match self.ron_repo_type.as_str() {
"rust" => {
if let Some(archive_path) = &self.ron_archive_path {
let base_url = self
.ron_base_url
.clone()
.unwrap_or_else(|| "https://127.0.0.1:8443".to_string());
let repo = RustRepoZnippy::with_archive_and_url(
self.ron_name.clone(),
PathBuf::from(archive_path),
base_url,
)?;
self.backend_repository = Some(Arc::new(repo));
} else {
let dir = self.ron_data_dir.clone().ok_or_else(|| {
anyhow::anyhow!(
"Rust file-backed repository requires ron_data_dir (storage directory)"
)
})?;
let base_url = self
.ron_base_url
.clone()
.unwrap_or_else(|| "https://127.0.0.1:8443".to_string());
let repo = RustRepo::new(self.ron_name.clone(), PathBuf::from(dir), base_url);
self.backend_repository = Some(Arc::new(repo));
}
Ok(())
}
"maven3" => znippy_backed!(MavenRepoZnippy, "Maven3"),
"pip" => znippy_backed!(PipRepoZnippy, "Pip"),
"npm" => znippy_backed!(NpmRepoZnippy, "Npm"),
"nuget" => znippy_backed!(NugetRepoZnippy, "Nuget"),
"go" => znippy_backed!(GoRepoZnippy, "Go"),
"gem" => znippy_backed!(GemRepoZnippy, "Gem"),
"deb" => znippy_backed!(DebRepoZnippy, "Deb"),
"rpm" => znippy_backed!(RpmRepoZnippy, "Rpm"),
"helm" => znippy_backed!(HelmRepoZnippy, "Helm"),
"docker" => znippy_backed!(DockerRepoZnippy, "Docker"),
"oci" => {
let dir = self
.ron_data_dir
.clone()
.unwrap_or_else(|| format!("/var/lib/holger/{}", self.ron_name));
let repo = OciRepoFile::new(self.ron_name.clone(), PathBuf::from(dir))?;
self.backend_repository = Some(Arc::new(repo));
Ok(())
}
"conda" => znippy_backed!(CondaRepoZnippy, "Conda"),
"composer" => znippy_backed!(ComposerRepoZnippy, "Composer"),
"znippy" => znippy_backed!(ZnippyRepoZnippy, "Znippy"),
other => anyhow::bail!("Unsupported repository type: {}", other),
}
}
}
#[derive(Serialize, Deserialize)]
pub struct RepositoryIO {
pub ron_storage_endpoint: String,
pub ron_exposed_endpoint: String,
#[serde(skip_serializing, skip_deserializing, default = "std::ptr::null")]
pub wired_storage: *const StorageEndpoint,
#[serde(skip_serializing, skip_deserializing, default = "std::ptr::null")]
pub wired_exposed: *const ExposedEndpoint,
}