use std::{fmt, path::PathBuf};
use crate::{
db,
stelae::{archive::Archive, stele::Stele, types::repositories::Repository},
utils::archive::get_name_parts,
};
pub trait Global {
fn archive(&self) -> &Archive;
fn db(&self) -> &db::DatabaseConnection;
}
#[derive(Debug, Clone)]
pub struct App {
pub archive: Archive,
pub db: db::DatabaseConnection,
}
impl Global for App {
fn archive(&self) -> &Archive {
&self.archive
}
fn db(&self) -> &db::DatabaseConnection {
&self.db
}
}
pub struct RepoData {
pub archive_path: PathBuf,
pub path: PathBuf,
pub org: String,
pub name: String,
pub serve: String,
}
impl RepoData {
#[must_use]
pub fn new(archive_path: &str, org: &str, name: &str, serve: &str) -> Self {
let mut repo_path = archive_path.to_owned();
repo_path = format!("{repo_path}/{org}/{name}");
Self {
archive_path: PathBuf::from(archive_path),
path: PathBuf::from(&repo_path),
org: org.to_owned(),
name: name.to_owned(),
serve: serve.to_owned(),
}
}
}
pub struct Shared {
pub fallback: Option<RepoData>,
}
impl fmt::Debug for RepoData {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(
formatter,
"Repo for {} in the archive at {}",
self.name,
self.path.display()
)
}
}
impl fmt::Debug for Shared {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let fb = &self.fallback;
match fb.as_ref() {
Some(fallback) => write!(
formatter,
"Repo for {} in the archive at {}",
fallback.name,
fallback.path.display()
),
None => write!(formatter, "No fallback repo"),
}
}
}
#[allow(clippy::missing_trait_methods)]
impl Clone for RepoData {
fn clone(&self) -> Self {
Self {
archive_path: self.archive_path.clone(),
path: self.path.clone(),
org: self.org.clone(),
name: self.name.clone(),
serve: self.serve.clone(),
}
}
}
#[allow(clippy::missing_trait_methods)]
impl Clone for Shared {
fn clone(&self) -> Self {
Self {
fallback: self.fallback.clone(),
}
}
}
pub fn init_repo(repo: &Repository, stele: &Stele) -> anyhow::Result<RepoData> {
let custom = &repo.custom;
let (org, name) = get_name_parts(&repo.name)?;
Ok(RepoData::new(
&stele.archive_path.to_string_lossy(),
&org,
&name,
&custom.serve,
))
}
pub fn init_shared(stele: &Stele) -> anyhow::Result<Shared> {
let fallback = stele
.get_fallback_repo()
.map(|repo| {
let (org, name) = get_name_parts(&repo.name)?;
Ok::<RepoData, anyhow::Error>(RepoData::new(
&stele.archive_path.to_string_lossy(),
&org,
&name,
&repo.custom.serve,
))
})
.transpose()?;
Ok(Shared { fallback })
}