use super::{RestoreApplyJournal, RestoreApplyJournalError, RestorePlan, RestorePlanError};
use crate::persistence::{PersistenceError, create_json_durable, read_json, write_json_durable};
use std::{io, path::Path};
use thiserror::Error as ThisError;
#[derive(Debug, ThisError)]
pub enum RestorePersistenceError {
#[error("restore apply journal conflicts with the existing recovery document: {path}")]
ApplyJournalConflict { path: String },
#[error(transparent)]
InvalidPlan(#[from] RestorePlanError),
#[error(transparent)]
InvalidJournal(#[from] RestoreApplyJournalError),
#[error(transparent)]
Persistence(#[from] PersistenceError),
#[error("restore plan conflicts with the existing recovery document: {path}")]
PlanConflict { path: String },
}
pub fn create_or_adopt_restore_plan(
path: &Path,
plan: &RestorePlan,
) -> Result<(), RestorePersistenceError> {
plan.validate()?;
match read_json::<RestorePlan>(path) {
Ok(existing) => {
existing.validate()?;
if existing == *plan {
Ok(())
} else {
Err(RestorePersistenceError::PlanConflict {
path: path.display().to_string(),
})
}
}
Err(PersistenceError::Io(error)) if error.kind() == io::ErrorKind::NotFound => {
create_json_durable(path, plan).map_err(RestorePersistenceError::from)
}
Err(error) => Err(error.into()),
}
}
pub fn create_or_adopt_restore_apply_journal(
path: &Path,
journal: &RestoreApplyJournal,
) -> Result<(), RestorePersistenceError> {
journal.validate()?;
match read_json::<RestoreApplyJournal>(path) {
Ok(existing) => {
existing.validate()?;
if existing == *journal {
Ok(())
} else {
Err(RestorePersistenceError::ApplyJournalConflict {
path: path.display().to_string(),
})
}
}
Err(PersistenceError::Io(error)) if error.kind() == io::ErrorKind::NotFound => {
create_json_durable(path, journal).map_err(RestorePersistenceError::from)
}
Err(error) => Err(error.into()),
}
}
pub fn write_restore_plan(path: &Path, plan: &RestorePlan) -> Result<(), RestorePersistenceError> {
plan.validate()?;
write_json_durable(path, plan)?;
Ok(())
}
pub fn write_restore_apply_journal(
path: &Path,
journal: &RestoreApplyJournal,
) -> Result<(), RestorePersistenceError> {
journal.validate()?;
write_json_durable(path, journal)?;
Ok(())
}