summaryrefslogtreecommitdiffstats
path: root/src/walk.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/walk.rs')
-rw-r--r--src/walk.rs140
1 files changed, 0 insertions, 140 deletions
diff --git a/src/walk.rs b/src/walk.rs
deleted file mode 100644
index f661c4cf..00000000
--- a/src/walk.rs
+++ /dev/null
@@ -1,140 +0,0 @@
-/*!
-The walk module implements a recursive directory iterator (using the `walkdir`)
-crate that can efficiently skip and ignore files and directories specified in
-a user's ignore patterns.
-*/
-
-use walkdir::{self, DirEntry, WalkDir, WalkDirIterator};
-
-use ignore::Ignore;
-
-/// Iter is a recursive directory iterator over file paths in a directory.
-/// Only file paths should be searched are yielded.
-pub struct Iter {
- ig: Ignore,
- it: WalkEventIter,
-}
-
-impl Iter {
- /// Create a new recursive directory iterator using the ignore patterns
- /// and walkdir iterator given.
- pub fn new(ig: Ignore, wd: WalkDir) -> Iter {
- Iter {
- ig: ig,
- it: WalkEventIter::from(wd),
- }
- }
-
- /// Returns true if this entry should be skipped.
- #[inline(always)]
- fn skip_entry(&self, ent: &DirEntry) -> bool {
- if ent.depth() == 0 {
- // Never skip the root directory.
- return false;
- }
- if self.ig.ignored(ent.path(), ent.file_type().is_dir()) {
- return true;
- }
- false
- }
-}
-
-impl Iterator for Iter {
- type Item = DirEntry;
-
- #[inline(always)]
- fn next(&mut self) -> Option<DirEntry> {
- while let Some(ev) = self.it.next() {
- match ev {
- Err(err) => {
- eprintln!("{}", err);
- }
- Ok(WalkEvent::Exit) => {
- self.ig.pop();
- }
- Ok(WalkEvent::Dir(ent)) => {
- if self.skip_entry(&ent) {
- self.it.it.skip_current_dir();
- // Still need to push this on the stack because we'll
- // get a WalkEvent::Exit event for this dir. We don't
- // care if it errors though.
- let _ = self.ig.push(ent.path());
- continue;
- }
- if let Err(err) = self.ig.push(ent.path()) {
- eprintln!("{}", err);
- self.it.it.skip_current_dir();
- continue;
- }
- }
- Ok(WalkEvent::File(ent)) => {
- if self.skip_entry(&ent) {
- continue;
- }
- // If this isn't actually a file (e.g., a symlink), then
- // skip it.
- if !ent.file_type().is_file() {
- continue;
- }
- return Some(ent);
- }
- }
- }
- None
- }
-}
-
-/// WalkEventIter transforms a WalkDir iterator into an iterator that more
-/// accurately describes the directory tree. Namely, it emits events that are
-/// one of three types: directory, file or "exit." An "exit" event means that
-/// the entire contents of a directory have been enumerated.
-struct WalkEventIter {
- depth: usize,
- it: walkdir::Iter,
- next: Option<Result<DirEntry, walkdir::Error>>,
-}
-
-#[derive(Debug)]
-enum WalkEvent {
- Dir(DirEntry),
- File(DirEntry),
- Exit,
-}
-
-impl From<WalkDir> for WalkEventIter {
- fn from(it: WalkDir) -> WalkEventIter {
- WalkEventIter { depth: 0, it: it.into_iter(), next: None }
- }
-}
-
-impl Iterator for WalkEventIter {
- type Item = walkdir::Result<WalkEvent>;
-
- #[inline(always)]
- fn next(&mut self) -> Option<walkdir::Result<WalkEvent>> {
- let dent = self.next.take().or_else(|| self.it.next());
- let depth = match dent {
- None => 0,
- Some(Ok(ref dent)) => dent.depth(),
- Some(Err(ref err)) => err.depth(),
- };
- if depth < self.depth {
- self.depth -= 1;
- self.next = dent;
- return Some(Ok(WalkEvent::Exit));
- }
- self.depth = depth;
- match dent {
- None => None,
- Some(Err(err)) => Some(Err(err)),
- Some(Ok(dent)) => {
- if dent.file_type().is_dir() {
- self.depth += 1;
- Some(Ok(WalkEvent::Dir(dent)))
- } else {
- Some(Ok(WalkEvent::File(dent)))
- }
- }
- }
- }
-}