dry4rust/cli/checking/stale_report.rs
1// Copyright (c) 2026 Matjaz Domen Pecan
2// Copyright 2026 Umberto Gotti <umberto.gotti@umbertogotti.dev>
3// Licensed under the MIT License
4// SPDX-License-Identifier: MIT
5
6use crate::suppression::ignore_entry::IgnoreEntry;
7
8/// What `cleanup` found, and the words it uses to say so.
9///
10/// The two halves of `cleanup` -- listing stale entries and removing them --
11/// print the same three things in the same order and differ only in tense.
12/// Holding the tense here leaves one printing path instead of two.
13pub struct StaleReport<'a> {
14 entries: Vec<&'a IgnoreEntry>,
15 removed: bool,
16}
17
18impl<'a> StaleReport<'a> {
19 /// Entries that would go, had this not been a dry run.
20 #[must_use]
21 pub const fn dry_run(entries: Vec<&'a IgnoreEntry>) -> Self {
22 Self {
23 entries,
24 removed: false,
25 }
26 }
27
28 /// Entries that have gone.
29 #[must_use]
30 pub const fn removed(entries: Vec<&'a IgnoreEntry>) -> Self {
31 Self {
32 entries,
33 removed: true,
34 }
35 }
36
37 /// Whether the ignore file held nothing stale.
38 #[must_use]
39 pub const fn is_empty(&self) -> bool {
40 self.entries.is_empty()
41 }
42
43 /// The entries themselves, in the order they were found.
44 #[must_use]
45 pub fn entries(&self) -> &[&'a IgnoreEntry] {
46 &self.entries
47 }
48
49 /// The line introducing the list.
50 #[must_use]
51 pub const fn heading(&self) -> &'static str {
52 if self.removed {
53 "Removed stale entries:"
54 } else {
55 "Stale entries (dry run):"
56 }
57 }
58
59 /// The line closing it, which is where the tense shows.
60 #[must_use]
61 pub fn summary(&self) -> String {
62 let count = self.entries.len();
63 if self.removed {
64 format!("\nRemoved {count} stale entries.")
65 } else {
66 format!("\n{count} stale entries would be removed.")
67 }
68 }
69}