Skip to main content

canic_cli/backup/preflight/
mod.rs

1pub use canic_backup::preflight::BackupPreflightReport;
2use canic_backup::preflight::{BackupPreflightConfig, BackupPreflightError, run_backup_preflight};
3
4use super::{BackupCommandError, BackupPreflightOptions};
5
6/// Run all no-mutation backup checks and write standard preflight artifacts.
7pub fn backup_preflight(
8    options: &BackupPreflightOptions,
9) -> Result<BackupPreflightReport, BackupCommandError> {
10    let report = run_backup_preflight(&BackupPreflightConfig {
11        backup_dir: options.dir.clone(),
12        out_dir: options.out_dir.clone(),
13        mapping: options.mapping.clone(),
14    })
15    .map_err(BackupCommandError::from)?;
16
17    enforce_preflight_requirements(options, &report)?;
18    Ok(report)
19}
20
21// Enforce caller-requested preflight requirements after all artifacts are written.
22fn enforce_preflight_requirements(
23    options: &BackupPreflightOptions,
24    report: &BackupPreflightReport,
25) -> Result<(), BackupCommandError> {
26    if options.require_design_v1 && !report.manifest_design_v1_ready {
27        return Err(BackupCommandError::DesignConformanceNotReady {
28            backup_id: report.backup_id.clone(),
29        });
30    }
31
32    if !options.require_restore_ready || report.restore_ready {
33        return Ok(());
34    }
35
36    Err(BackupCommandError::RestoreNotReady {
37        backup_id: report.backup_id.clone(),
38        reasons: report.restore_readiness_reasons.clone(),
39    })
40}
41
42impl From<BackupPreflightError> for BackupCommandError {
43    // Preserve the public CLI error variants while delegating preflight work to canic-backup.
44    fn from(error: BackupPreflightError) -> Self {
45        match error {
46            BackupPreflightError::IncompleteJournal {
47                backup_id,
48                total_artifacts,
49                pending_artifacts,
50            } => Self::IncompleteJournal {
51                backup_id,
52                total_artifacts,
53                pending_artifacts,
54            },
55            BackupPreflightError::Io(error) => Self::Io(error),
56            BackupPreflightError::Json(error) => Self::Json(error),
57            BackupPreflightError::Persistence(error) => Self::Persistence(error),
58            BackupPreflightError::RestorePlan(error) => Self::RestorePlan(error),
59        }
60    }
61}