Skip to main content

cargo_reclaim/executor/
report.rs

1use crate::persistence::PlanId;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub struct ApplyReport {
5    pub plan_id: PlanId,
6    pub dry_run: bool,
7    pub entries: Vec<ApplyEntryResult>,
8    pub totals: ApplyTotals,
9}
10
11#[derive(Debug, Clone, PartialEq, Eq, Default)]
12pub struct ApplyTotals {
13    pub entry_count: usize,
14    pub delete_candidate_count: usize,
15    pub would_delete_count: usize,
16    pub skipped_count: usize,
17    pub stale_skip_count: usize,
18    pub applied_count: usize,
19    pub failed_count: usize,
20    pub would_delete_bytes: u64,
21    pub applied_bytes: u64,
22}
23
24impl ApplyReport {
25    pub(super) fn new(plan_id: PlanId, entries: Vec<ApplyEntryResult>) -> Self {
26        Self {
27            plan_id,
28            dry_run: true,
29            totals: ApplyTotals::from_entries(&entries),
30            entries,
31        }
32    }
33
34    pub(super) fn executed(plan_id: PlanId, entries: Vec<ApplyEntryResult>) -> Self {
35        Self {
36            plan_id,
37            dry_run: false,
38            totals: ApplyTotals::from_entries(&entries),
39            entries,
40        }
41    }
42}
43
44impl ApplyTotals {
45    fn from_entries(entries: &[ApplyEntryResult]) -> Self {
46        let mut totals = Self {
47            entry_count: entries.len(),
48            ..Self::default()
49        };
50
51        for entry in entries {
52            if entry.planned_action == "delete" {
53                totals.delete_candidate_count += 1;
54            }
55
56            match entry.status {
57                ApplyEntryStatus::WouldDelete => {
58                    totals.would_delete_count += 1;
59                    totals.would_delete_bytes =
60                        totals.would_delete_bytes.saturating_add(entry.size_bytes);
61                }
62                ApplyEntryStatus::Deleted => {
63                    totals.applied_count += 1;
64                    totals.applied_bytes = totals
65                        .applied_bytes
66                        .saturating_add(entry.deleted_bytes.unwrap_or(entry.size_bytes));
67                }
68                ApplyEntryStatus::NotPlannedForDeletion => totals.skipped_count += 1,
69                ApplyEntryStatus::SkipStalePlan => {
70                    totals.skipped_count += 1;
71                    totals.stale_skip_count += 1;
72                }
73                ApplyEntryStatus::DeleteFailed => totals.failed_count += 1,
74            }
75        }
76
77        totals
78    }
79}
80
81#[derive(Debug, Clone, PartialEq, Eq)]
82pub struct ApplyEntryResult {
83    pub path: String,
84    pub planned_action: String,
85    pub status: ApplyEntryStatus,
86    pub reason: String,
87    pub size_bytes: u64,
88    pub deleted_bytes: Option<u64>,
89}
90
91impl ApplyEntryResult {
92    pub(super) fn new(
93        path: String,
94        planned_action: String,
95        status: ApplyEntryStatus,
96        size_bytes: u64,
97        reason: impl Into<String>,
98    ) -> Self {
99        Self {
100            path,
101            planned_action,
102            status,
103            reason: reason.into(),
104            size_bytes,
105            deleted_bytes: None,
106        }
107    }
108}
109
110#[derive(Debug, Clone, Copy, PartialEq, Eq)]
111pub enum ApplyEntryStatus {
112    WouldDelete,
113    Deleted,
114    NotPlannedForDeletion,
115    SkipStalePlan,
116    DeleteFailed,
117}