Skip to main content

ralph/queue/repair/
types.rs

1//! Purpose: Data models for queue repair planning.
2//!
3//! Responsibilities:
4//! - Describe the user-visible repair report (`RepairReport`).
5//! - Describe the planned repair mutation (`QueueRepairPlan`) that apply flows consume.
6//! - Encode the planner scope (`RepairScope`) shared between maintenance and
7//!   full repair planning.
8//!
9//! Scope:
10//! - Pure data plus tiny accessors; no IO, validation, or planning logic.
11//!
12//! Usage:
13//! - `crate::queue::repair::planning` builds `QueueRepairPlan` and `RepairReport`.
14//! - `crate::queue::repair::apply` consumes `QueueRepairPlan` to validate and persist.
15//!
16//! Invariants/Assumptions:
17//! - `QueueRepairPlan::has_changes` is the single source of truth for whether
18//!   apply must validate, snapshot undo, and save.
19//! - Field visibility stays `pub(super)` for plan internals so only the repair
20//!   facade can construct or mutate plan state.
21
22use crate::contracts::QueueFile;
23use serde::Serialize;
24
25#[derive(Debug, Default, Clone, Serialize)]
26pub struct RepairReport {
27    pub fixed_tasks: usize,
28    pub remapped_ids: Vec<(String, String)>,
29    pub fixed_timestamps: usize,
30}
31
32impl RepairReport {
33    pub fn is_empty(&self) -> bool {
34        self.fixed_tasks == 0 && self.remapped_ids.is_empty() && self.fixed_timestamps == 0
35    }
36}
37
38#[derive(Debug, Clone)]
39pub struct QueueRepairPlan {
40    pub(super) active: QueueFile,
41    pub(super) done: QueueFile,
42    pub(super) report: RepairReport,
43    pub(super) queue_changed: bool,
44    pub(super) done_changed: bool,
45}
46
47#[derive(Clone, Copy, Debug, Eq, PartialEq)]
48pub(super) enum RepairScope {
49    Maintenance,
50    Full,
51}
52
53impl QueueRepairPlan {
54    pub fn has_changes(&self) -> bool {
55        self.queue_changed || self.done_changed
56    }
57
58    pub fn report(&self) -> &RepairReport {
59        &self.report
60    }
61
62    pub fn into_parts(self) -> (QueueFile, QueueFile, RepairReport) {
63        (self.active, self.done, self.report)
64    }
65}