weavatrix-scan 0.3.0

Deterministic, safe repository scanner for code intelligence
Documentation
use super::visit::{ParallelVisitReport, WalkControl, WalkEvent};
use crate::FileIdentity;
use crate::control::CancellationToken;
use crate::walker::{ErrorPolicy, WalkError, WalkOptions, Walker};
use std::path::Path;

pub(super) fn visit_serial<F>(
    root: &Path,
    options: WalkOptions,
    skip_stdout: Option<FileIdentity>,
    cancellation: &CancellationToken,
    visitor: F,
) -> Result<ParallelVisitReport, WalkError>
where
    F: for<'entry> Fn(WalkEvent<'entry>) -> WalkControl + Sync,
{
    let mut walker_options = options;
    walker_options.error_policy = ErrorPolicy::Continue;
    let mut walker = Walker::with_behavior(root, walker_options, None, None, skip_stdout, false)?;
    let mut visited = 0_u64;
    let mut errors = Vec::new();
    let mut quit = false;
    while !cancellation.is_cancelled() && !quit {
        let Some(item) = walker.next() else {
            break;
        };
        match item {
            Ok(entry) => {
                visited = visited.saturating_add(1);
                match visitor(WalkEvent::Entry(&entry)) {
                    WalkControl::Skip if entry.is_dir() => walker.skip_current_dir(),
                    WalkControl::Continue | WalkControl::Skip => {}
                    WalkControl::Quit => quit = true,
                }
            }
            Err(error) => {
                let control = visitor(WalkEvent::Error(&error));
                errors.push(error);
                if options.error_policy == ErrorPolicy::Abort {
                    return Err(errors.remove(0));
                }
                quit = control == WalkControl::Quit;
            }
        }
    }
    Ok(ParallelVisitReport {
        visited,
        errors,
        quit,
        cancelled: cancellation.is_cancelled(),
    })
}