pub trait WalkVisitor:
Send
+ Sync
+ 'static {
type Summary: WalkSummary;
type DirContext: Clone + Send + Sync + 'static;
type DirState: Send;
// Required methods
fn root_dir_context(&self) -> Self::DirContext;
fn permit_kind(&self) -> PermitKind;
fn want_permit(&self, hint: Option<EntryKind>) -> bool;
fn fail_early(&self) -> bool;
fn filter(&self) -> Option<&FilterSettings>;
fn visit_leaf(
&self,
cx: &EntryCx,
parent_ctx: &Self::DirContext,
handle: Handle,
kind: EntryKind,
permit: Option<LeafPermit>,
) -> impl Future<Output = Result<Self::Summary, OperationError<Self::Summary>>> + Send;
fn dir_pre(
&self,
cx: &EntryCx,
parent_ctx: &Self::DirContext,
handle: &Handle,
) -> impl Future<Output = DirPreResult<Self>> + Send;
fn dir_post(
&self,
cx: &EntryCx,
state: Self::DirState,
processed: &ProcessedChildren,
child_result: Result<Self::Summary, OperationError<Self::Summary>>,
) -> impl Future<Output = Result<Self::Summary, OperationError<Self::Summary>>> + Send;
// Provided method
fn on_skip(
&self,
_cx: &EntryCx,
_kind: EntryKind,
_skip_result: &FilterResult,
) -> Self::Summary { ... }
}Expand description
A tool’s policy for a single-tree safe walk.
The driver calls these to make the per-entry decisions it cannot know itself;
it owns everything else (enumeration, permit lifecycle, spawning, the
drop-before-recurse invariant, error fold). All futures are + Send (RPITIT)
so the driver can spawn them; the visitor is shared as Arc<V>.
Required Associated Types§
Sourcetype Summary: WalkSummary
type Summary: WalkSummary
Per-run summary type (the tool’s Summary).
Sourcetype DirContext: Clone + Send + Sync + 'static
type DirContext: Clone + Send + Sync + 'static
Inherited per-directory context: what a directory’s children need from
that directory (an “inherited attribute” of the tree walk). The driver
clones it into each child task and hands it to the child’s
Self::visit_leaf / Self::dir_pre.
This is the single-tree driver’s bridge to copy’s second (destination)
tree: copy puts the open destination directory handle (plus its freshness)
here, so each child can create/overwrite its own destination entry without
the driver ever modeling a second tree. chmod and rm — which only ever
need the source parent the driver already provides — use ().
Sourcetype DirState: Send
type DirState: Send
State threaded from Self::dir_pre to Self::dir_post within one
task (so it need not be Send across the per-child spawn boundary —
dir_pre/recurse/dir_post all run in the same task).
Required Methods§
Sourcefn root_dir_context(&self) -> Self::DirContext
fn root_dir_context(&self) -> Self::DirContext
The inherited context for the walk root’s children — the seed of the
DirContext chain. copy returns its top-level destination directory here;
chmod/rm return (). (The root entry itself is processed with this same
context as its “parent” context.)
Sourcefn permit_kind(&self) -> PermitKind
fn permit_kind(&self) -> PermitKind
Which backpressure pool a leaf permit comes from for this tool.
Sourcefn want_permit(&self, hint: Option<EntryKind>) -> bool
fn want_permit(&self, hint: Option<EntryKind>) -> bool
Whether to pre-acquire a leaf permit for a child with this getdents
d_type hint. Must return false for a hinted directory (it would
recurse and a held permit could deadlock); the canonical policy is
“known non-directory only”. hint == None (DT_UNKNOWN) is a tool choice.
Sourcefn fail_early(&self) -> bool
fn fail_early(&self) -> bool
Whether the walk stops at the first error (--fail-early).
Sourcefn filter(&self) -> Option<&FilterSettings>
fn filter(&self) -> Option<&FilterSettings>
The active filter, if any (drives walk::filter_is_dir /
walk::should_skip_entry_ref).
Sourcefn visit_leaf(
&self,
cx: &EntryCx,
parent_ctx: &Self::DirContext,
handle: Handle,
kind: EntryKind,
permit: Option<LeafPermit>,
) -> impl Future<Output = Result<Self::Summary, OperationError<Self::Summary>>> + Send
fn visit_leaf( &self, cx: &EntryCx, parent_ctx: &Self::DirContext, handle: Handle, kind: EntryKind, permit: Option<LeafPermit>, ) -> impl Future<Output = Result<Self::Summary, OperationError<Self::Summary>>> + Send
Process a non-directory entry (file / symlink / special). parent_ctx is
the inherited context of the directory containing this entry (copy’s
destination parent + freshness). The pre-acquired permit (if any) is held
for the duration and dropped on return.
Sourcefn dir_pre(
&self,
cx: &EntryCx,
parent_ctx: &Self::DirContext,
handle: &Handle,
) -> impl Future<Output = DirPreResult<Self>> + Send
fn dir_pre( &self, cx: &EntryCx, parent_ctx: &Self::DirContext, handle: &Handle, ) -> impl Future<Output = DirPreResult<Self>> + Send
Pre-order step for a directory entry, run after the leaf permit has been
dropped and before the contents are walked. parent_ctx is the inherited
context of the containing directory. Returns DirAction::Skip to prune
the subtree or DirAction::Descend to walk it (supplying the child
context for this directory’s own children, and the dir_post state).
chmod applies the pre-order mode change here (unless deferred) and opens
the dir; copy resolves the destination directory (mkdir/overwrite/skip) and
puts it in the child context; rm snapshots metadata and arms its
RelaxedDirGuard.
Sourcefn dir_post(
&self,
cx: &EntryCx,
state: Self::DirState,
processed: &ProcessedChildren,
child_result: Result<Self::Summary, OperationError<Self::Summary>>,
) -> impl Future<Output = Result<Self::Summary, OperationError<Self::Summary>>> + Send
fn dir_post( &self, cx: &EntryCx, state: Self::DirState, processed: &ProcessedChildren, child_result: Result<Self::Summary, OperationError<Self::Summary>>, ) -> impl Future<Output = Result<Self::Summary, OperationError<Self::Summary>>> + Send
Post-order step for a directory entry, run after its contents are walked,
in the same task as dir_pre. state is the DirAction::Descend state;
processed lists the spawned children; child_result is the contents’ folded
outcome — Ok(summary) when every child succeeded, or Err carrying the
combined child error and the partial summary when one or more children failed
without fail_early. (Neither has dir_pre’s own contribution folded in
— the visitor carries that in state and folds it here.)
dir_post is not called when fail_early is set and a child failed: that
case aborts the subtree immediately (the surrounding JoinSet drops, aborting
siblings) and the error is returned without any post-order work — so a
fail-early abort never applies post-order finalization (copy’s directory
metadata / --delete prune). When fail_early is unset, dir_post IS called
with Err(..) so the visitor can still apply safe post-order finalization
(copy applies directory metadata even after a partial failure, but skips the
destructive --delete prune) and then return the combined error.
copy applies directory metadata, empty-dir cleanup, and --delete prune;
chmod applies the deferred post-order change; rm runs the time filter, the
rmdir, and defuses its guard. A visitor that wants the historical
“finalize only on full success” behavior simply propagates the Err.
Provided Methods§
Sourcefn on_skip(
&self,
_cx: &EntryCx,
_kind: EntryKind,
_skip_result: &FilterResult,
) -> Self::Summary
fn on_skip( &self, _cx: &EntryCx, _kind: EntryKind, _skip_result: &FilterResult, ) -> Self::Summary
Account for an entry the filter excluded, returning its summary
contribution. Called by the driver for each filtered-out child instead of
spawning it, so the tool’s *_skipped counters and dry-run skip reporting
stay tool-owned (the driver is generic over the summary and dry-run mode).
kind is the cheap getdents-hint classification (DT_UNKNOWN treated as a
file), matching the per-tool walks’ skip dispatch; skip_result is the
FilterResult that caused the exclusion. The driver still increments the
shared progress counter via EntryKind::inc_skipped — override only to
add the summary counters and the --dry-run “skip …” line.
The default does nothing (returns Default), which suits metadata-only
walks and the smoke tests; copy/chmod/rm override it to mirror their
existing skipped_summary_for + report_skip behavior.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".