Skip to main content

file_engine/analysis/
progress.rs

1use std::path::PathBuf;
2
3use tokio::sync::mpsc;
4
5/// Deliberately a separate, smaller enum from `crate::progress::Progress`
6/// rather than a reuse: `Progress` (and the `Handle<T>` it's threaded
7/// through) live behind the `operations` feature, which `analyze`
8/// doesn't require — see `AnalysisHandle`'s doc comment for the same
9/// reasoning applied one level up.
10///
11/// `#[non_exhaustive]` for the same reason as `Progress`: adding a
12/// variant later shouldn't be a breaking change for an exhaustive match.
13#[derive(Debug, Clone)]
14#[non_exhaustive]
15pub enum AnalysisProgress {
16    /// Always emitted first, exactly once. `estimated_entries` is `Some`
17    /// only when `AnalyzeBuilder::estimate_total(true)` was set — getting
18    /// a count requires a full extra pass over the tree (stat-ing every
19    /// file against the same filters as the real walk), so it's `None`
20    /// by default rather than paying that cost unconditionally.
21    Started { estimated_entries: Option<usize> },
22    /// Emitted once per matched entry (after filters, not per entry
23    /// walked) as the tree is scanned.
24    EntryAnalyzed { path: PathBuf },
25    /// Emitted once per file as it finishes content-hashing during
26    /// duplicate detection — the slow phase, so this is the only signal
27    /// of liveness while it runs. Only emitted when
28    /// `.detect_duplicates(true)` is set.
29    #[cfg(feature = "checksum")]
30    EntryHashed { path: PathBuf },
31}
32
33#[derive(Clone)]
34pub(crate) struct AnalysisProgressReporter {
35    tx: mpsc::UnboundedSender<AnalysisProgress>,
36}
37
38impl AnalysisProgressReporter {
39    pub(crate) fn new(tx: mpsc::UnboundedSender<AnalysisProgress>) -> Self {
40        Self { tx }
41    }
42
43    /// A closed receiver means nobody's listening — not a failure, just
44    /// nothing to report to. Mirrors `ProgressReporter::send`.
45    pub(crate) fn send(&self, progress: AnalysisProgress) {
46        let _ = self.tx.send(progress);
47    }
48}