Skip to main content

file_engine/planner/
outcome.rs

1use std::path::PathBuf;
2use std::time::Duration;
3
4use crate::error::Error;
5use crate::profiler::Entry;
6
7/// `#[non_exhaustive]`: a downstream `match` needs a `_` arm, so a new
8/// way for an operation to stop early isn't a breaking change. Same
9/// reasoning as `Progress`.
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11#[non_exhaustive]
12pub enum StopReason {
13    Fatal,
14    AbortOnError,
15    Cancelled,
16    Undo,
17}
18
19/// Aggregate result of running an `ExecutionPlan`. Replaces a bare
20/// `Result<(), Error>` because `ErrorStrategy::ContinueAndCollect` can
21/// finish with a mix of successes and failures that a single `Result`
22/// can't represent.
23/// `#[non_exhaustive]`: an output type, built by this crate and read by
24/// the caller, so blocking downstream construction costs nothing —
25/// `Default` and `..`-destructuring both still work. Adding `duration`
26/// was a breaking change for exhaustive struct literals; marked now so
27/// the next field isn't, same reasoning as `Progress`.
28#[derive(Debug, Default)]
29#[non_exhaustive]
30pub struct OperationOutcome {
31    pub succeeded: Vec<Entry>,
32    pub failed: Vec<(Entry, Error)>,
33    /// Populated only by move's deferred deletion sweep: entries that
34    /// copied successfully but whose original source could not be
35    /// removed afterward (data duplicated, not lost). Copy never
36    /// populates this field.
37    pub cleanup_failed: Vec<(Entry, Error)>,
38    pub stopped_early: Option<StopReason>,
39    /// Populated only by the directory-permissions pass
40    /// (`.preserve_permissions()`), which always runs to completion
41    /// regardless of individual failures and never affects
42    /// `stopped_early` — a directory `chmod` failure is a best-effort
43    /// finishing touch, not an interruption of the actual data transfer.
44    /// Unconditional (not `#[cfg(unix)]`-gated), same reasoning as
45    /// `Entry.mode`: avoids a platform-conditional shape for a type with
46    /// many existing construction sites. Always empty on non-Unix or
47    /// when permission preservation wasn't requested.
48    pub directories_failed: Vec<(PathBuf, Error)>,
49    /// Wall time the operation took, stamped where the outcome is
50    /// produced for the caller. The counterpart to `Handle::elapsed()`
51    /// for after the handle has been consumed by `.await`.
52    ///
53    /// `SyncOutcome`'s two outcomes are timed per phase, so they don't
54    /// sum to the whole run — the diff that precedes them belongs to
55    /// neither. `Handle::elapsed()` remains the figure for the run as a
56    /// whole.
57    ///
58    /// `Duration::ZERO` on a phase that never ran (sync's delete sweep
59    /// when the copy phase stopped early) and on outcomes built by hand
60    /// in tests, which take the `Default`.
61    pub duration: Duration,
62}