Skip to main content

canic_backup/restore/status/
mod.rs

1use super::{RestorePhase, RestorePlan, RestorePlanMember};
2use serde::{Deserialize, Serialize};
3
4///
5/// RestoreStatus
6///
7
8#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
9pub struct RestoreStatus {
10    pub status_version: u16,
11    pub backup_id: String,
12    pub source_environment: String,
13    pub source_root_canister: String,
14    pub topology_hash: String,
15    pub ready: bool,
16    pub readiness_reasons: Vec<String>,
17    pub verification_required: bool,
18    pub member_count: usize,
19    pub phase_count: usize,
20    #[serde(default)]
21    pub planned_snapshot_uploads: usize,
22    pub planned_snapshot_loads: usize,
23    pub planned_code_reinstalls: usize,
24    pub planned_verification_checks: usize,
25    #[serde(default)]
26    pub planned_operations: usize,
27    pub phases: Vec<RestoreStatusPhase>,
28}
29
30impl RestoreStatus {
31    /// Build the initial no-mutation restore status from a computed plan.
32    #[must_use]
33    pub fn from_plan(plan: &RestorePlan) -> Self {
34        Self {
35            status_version: 1,
36            backup_id: plan.backup_id.clone(),
37            source_environment: plan.source_environment.clone(),
38            source_root_canister: plan.source_root_canister.clone(),
39            topology_hash: plan.topology_hash.clone(),
40            ready: plan.readiness_summary.ready,
41            readiness_reasons: plan.readiness_summary.reasons.clone(),
42            verification_required: plan.verification_summary.verification_required,
43            member_count: plan.member_count,
44            phase_count: plan.ordering_summary.phase_count,
45            planned_snapshot_uploads: plan
46                .operation_summary
47                .effective_planned_snapshot_uploads(plan.member_count),
48            planned_snapshot_loads: plan.operation_summary.planned_snapshot_loads,
49            planned_code_reinstalls: plan.operation_summary.planned_code_reinstalls,
50            planned_verification_checks: plan.operation_summary.planned_verification_checks,
51            planned_operations: plan
52                .operation_summary
53                .effective_planned_operations(plan.member_count),
54            phases: plan
55                .phases
56                .iter()
57                .map(RestoreStatusPhase::from_plan_phase)
58                .collect(),
59        }
60    }
61}
62
63///
64/// RestoreStatusPhase
65///
66
67#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
68pub struct RestoreStatusPhase {
69    pub restore_group: u16,
70    pub members: Vec<RestoreStatusMember>,
71}
72
73impl RestoreStatusPhase {
74    // Build one status phase from one planned restore phase.
75    fn from_plan_phase(phase: &RestorePhase) -> Self {
76        Self {
77            restore_group: phase.restore_group,
78            members: phase
79                .members
80                .iter()
81                .map(RestoreStatusMember::from_plan_member)
82                .collect(),
83        }
84    }
85}
86
87///
88/// RestoreStatusMember
89///
90
91#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
92pub struct RestoreStatusMember {
93    pub source_canister: String,
94    pub target_canister: String,
95    pub role: String,
96    pub restore_group: u16,
97    pub phase_order: usize,
98    pub snapshot_id: String,
99    pub artifact_path: String,
100    pub state: RestoreMemberState,
101}
102
103impl RestoreStatusMember {
104    // Build one member status row from one planned restore member.
105    fn from_plan_member(member: &RestorePlanMember) -> Self {
106        Self {
107            source_canister: member.source_canister.clone(),
108            target_canister: member.target_canister.clone(),
109            role: member.role.clone(),
110            restore_group: member.restore_group,
111            phase_order: member.phase_order,
112            snapshot_id: member.source_snapshot.snapshot_id.clone(),
113            artifact_path: member.source_snapshot.artifact_path.clone(),
114            state: RestoreMemberState::Planned,
115        }
116    }
117}
118
119///
120/// RestoreMemberState
121///
122
123#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
124#[serde(rename_all = "kebab-case")]
125pub enum RestoreMemberState {
126    Planned,
127}