use crate::{
execution::BackupExecutionJournal,
journal::DownloadJournal,
manifest::DeploymentBackupManifest,
persistence::{
BackupExecutionIntegrityReport, BackupIntegrityReport, PersistenceError,
integrity::{verify_execution_integrity, verify_layout_integrity},
json::{read_json, write_json_atomic},
},
plan::BackupPlan,
};
use std::path::{Path, PathBuf};
const MANIFEST_FILE_NAME: &str = "deployment-backup-manifest.json";
const BACKUP_PLAN_FILE_NAME: &str = "backup-plan.json";
const JOURNAL_FILE_NAME: &str = "download-journal.json";
const EXECUTION_JOURNAL_FILE_NAME: &str = "backup-execution-journal.json";
#[derive(Clone, Debug)]
pub struct BackupLayout {
root: PathBuf,
}
impl BackupLayout {
#[must_use]
pub const fn new(root: PathBuf) -> Self {
Self { root }
}
#[must_use]
pub fn root(&self) -> &Path {
&self.root
}
#[must_use]
pub fn manifest_path(&self) -> PathBuf {
self.root.join(MANIFEST_FILE_NAME)
}
#[must_use]
pub fn backup_plan_path(&self) -> PathBuf {
self.root.join(BACKUP_PLAN_FILE_NAME)
}
#[must_use]
pub fn journal_path(&self) -> PathBuf {
self.root.join(JOURNAL_FILE_NAME)
}
#[must_use]
pub fn execution_journal_path(&self) -> PathBuf {
self.root.join(EXECUTION_JOURNAL_FILE_NAME)
}
pub fn write_manifest(
&self,
manifest: &DeploymentBackupManifest,
) -> Result<(), PersistenceError> {
manifest.validate()?;
write_json_atomic(&self.manifest_path(), manifest)
}
pub fn read_manifest(&self) -> Result<DeploymentBackupManifest, PersistenceError> {
let manifest = read_json(&self.manifest_path())?;
DeploymentBackupManifest::validate(&manifest)?;
Ok(manifest)
}
pub fn write_backup_plan(&self, plan: &BackupPlan) -> Result<(), PersistenceError> {
plan.validate()?;
write_json_atomic(&self.backup_plan_path(), plan)
}
pub fn read_backup_plan(&self) -> Result<BackupPlan, PersistenceError> {
let plan = read_json(&self.backup_plan_path())?;
BackupPlan::validate(&plan)?;
Ok(plan)
}
pub fn write_journal(&self, journal: &DownloadJournal) -> Result<(), PersistenceError> {
journal.validate()?;
write_json_atomic(&self.journal_path(), journal)
}
pub fn read_journal(&self) -> Result<DownloadJournal, PersistenceError> {
let journal = read_json(&self.journal_path())?;
DownloadJournal::validate(&journal)?;
Ok(journal)
}
pub fn write_execution_journal(
&self,
journal: &BackupExecutionJournal,
) -> Result<(), PersistenceError> {
journal.validate()?;
write_json_atomic(&self.execution_journal_path(), journal)
}
pub fn read_execution_journal(&self) -> Result<BackupExecutionJournal, PersistenceError> {
let journal = read_json(&self.execution_journal_path())?;
BackupExecutionJournal::validate(&journal)?;
Ok(journal)
}
pub fn verify_integrity(&self) -> Result<BackupIntegrityReport, PersistenceError> {
let manifest = self.read_manifest()?;
let journal = self.read_journal()?;
verify_layout_integrity(self, &manifest, &journal)
}
pub fn verify_execution_integrity(
&self,
) -> Result<BackupExecutionIntegrityReport, PersistenceError> {
let plan = self.read_backup_plan()?;
let journal = self.read_execution_journal()?;
verify_execution_integrity(&plan, &journal)
}
}