mirror of
https://github.com/BurntSushi/walkdir.git
synced 2025-09-30 15:10:30 +00:00
Remove WalkDirIterator (#58)
remove WalkDirIterator And make skip_current_dir and filter_entry inherent methods. Fixes #40.
This commit is contained in:
parent
133a11d538
commit
fb40eafaff
@ -70,7 +70,7 @@ This uses the `filter_entry` iterator adapter to avoid yielding hidden files
|
|||||||
and directories efficiently:
|
and directories efficiently:
|
||||||
|
|
||||||
```rust,no_run
|
```rust,no_run
|
||||||
use walkdir::{DirEntry, WalkDir, WalkDirIterator};
|
use walkdir::{DirEntry, WalkDir};
|
||||||
|
|
||||||
fn is_hidden(entry: &DirEntry) -> bool {
|
fn is_hidden(entry: &DirEntry) -> bool {
|
||||||
entry.file_name()
|
entry.file_name()
|
||||||
|
268
src/lib.rs
268
src/lib.rs
@ -16,9 +16,7 @@ walkdir = "1"
|
|||||||
|
|
||||||
# From the top
|
# From the top
|
||||||
|
|
||||||
The `WalkDir` type builds iterators. The `WalkDirIterator` trait provides
|
The `WalkDir` type builds iterators. The `DirEntry` type describes values yielded by the iterator.
|
||||||
methods for directory iterator adapters, such as efficiently pruning entries
|
|
||||||
during traversal. The `DirEntry` type describes values yielded by the iterator.
|
|
||||||
Finally, the `Error` type is a small wrapper around `std::io::Error` with
|
Finally, the `Error` type is a small wrapper around `std::io::Error` with
|
||||||
additional information, such as if a loop was detected while following symbolic
|
additional information, such as if a loop was detected while following symbolic
|
||||||
links (not enabled by default).
|
links (not enabled by default).
|
||||||
@ -68,7 +66,7 @@ This uses the `filter_entry` iterator adapter to avoid yielding hidden files
|
|||||||
and directories efficiently:
|
and directories efficiently:
|
||||||
|
|
||||||
```rust,no_run
|
```rust,no_run
|
||||||
use walkdir::{DirEntry, WalkDir, WalkDirIterator};
|
use walkdir::{DirEntry, WalkDir};
|
||||||
|
|
||||||
fn is_hidden(entry: &DirEntry) -> bool {
|
fn is_hidden(entry: &DirEntry) -> bool {
|
||||||
entry.file_name()
|
entry.file_name()
|
||||||
@ -342,91 +340,6 @@ impl IntoIterator for WalkDir {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A trait for recursive directory iterators.
|
|
||||||
pub trait WalkDirIterator: Iterator {
|
|
||||||
/// Skips the current directory.
|
|
||||||
///
|
|
||||||
/// This causes the iterator to stop traversing the contents of the least
|
|
||||||
/// recently yielded directory. This means any remaining entries in that
|
|
||||||
/// directory will be skipped (including sub-directories).
|
|
||||||
///
|
|
||||||
/// Note that the ergonomics of this method are questionable since it
|
|
||||||
/// borrows the iterator mutably. Namely, you must write out the looping
|
|
||||||
/// condition manually. For example, to skip hidden entries efficiently on
|
|
||||||
/// unix systems:
|
|
||||||
///
|
|
||||||
/// ```rust,no_run
|
|
||||||
/// use walkdir::{DirEntry, WalkDir, WalkDirIterator};
|
|
||||||
///
|
|
||||||
/// fn is_hidden(entry: &DirEntry) -> bool {
|
|
||||||
/// entry.file_name()
|
|
||||||
/// .to_str()
|
|
||||||
/// .map(|s| s.starts_with("."))
|
|
||||||
/// .unwrap_or(false)
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// let mut it = WalkDir::new("foo").into_iter();
|
|
||||||
/// loop {
|
|
||||||
/// let entry = match it.next() {
|
|
||||||
/// None => break,
|
|
||||||
/// Some(Err(err)) => panic!("ERROR: {}", err),
|
|
||||||
/// Some(Ok(entry)) => entry,
|
|
||||||
/// };
|
|
||||||
/// if is_hidden(&entry) {
|
|
||||||
/// if entry.file_type().is_dir() {
|
|
||||||
/// it.skip_current_dir();
|
|
||||||
/// }
|
|
||||||
/// continue;
|
|
||||||
/// }
|
|
||||||
/// println!("{}", entry.path().display());
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// You may find it more convenient to use the `filter_entry` iterator
|
|
||||||
/// adapter. (See its documentation for the same example functionality as
|
|
||||||
/// above.)
|
|
||||||
fn skip_current_dir(&mut self);
|
|
||||||
|
|
||||||
/// Yields only entries which satisfy the given predicate and skips
|
|
||||||
/// descending into directories that do not satisfy the given predicate.
|
|
||||||
///
|
|
||||||
/// The predicate is applied to all entries. If the predicate is
|
|
||||||
/// true, iteration carries on as normal. If the predicate is false, the
|
|
||||||
/// entry is ignored and if it is a directory, it is not descended into.
|
|
||||||
///
|
|
||||||
/// This is often more convenient to use than `skip_current_dir`. For
|
|
||||||
/// example, to skip hidden files and directories efficiently on unix
|
|
||||||
/// systems:
|
|
||||||
///
|
|
||||||
/// ```rust,no_run
|
|
||||||
/// use walkdir::{DirEntry, WalkDir, WalkDirIterator};
|
|
||||||
///
|
|
||||||
/// fn is_hidden(entry: &DirEntry) -> bool {
|
|
||||||
/// entry.file_name()
|
|
||||||
/// .to_str()
|
|
||||||
/// .map(|s| s.starts_with("."))
|
|
||||||
/// .unwrap_or(false)
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// for entry in WalkDir::new("foo")
|
|
||||||
/// .into_iter()
|
|
||||||
/// .filter_entry(|e| !is_hidden(e)) {
|
|
||||||
/// let entry = entry.unwrap();
|
|
||||||
/// println!("{}", entry.path().display());
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Note that the iterator will still yield errors for reading entries that
|
|
||||||
/// may not satisfy the predicate.
|
|
||||||
///
|
|
||||||
/// Note that entries skipped with `min_depth` and `max_depth` are not
|
|
||||||
/// passed to this predicate.
|
|
||||||
fn filter_entry<P>(self, predicate: P) -> FilterEntry<Self, P>
|
|
||||||
where Self: Sized, P: FnMut(&DirEntry) -> bool {
|
|
||||||
FilterEntry { it: self, predicate: predicate }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An iterator for recursively descending into a directory.
|
/// An iterator for recursively descending into a directory.
|
||||||
///
|
///
|
||||||
/// A value with this type must be constructed with the `WalkDir` type, which
|
/// A value with this type must be constructed with the `WalkDir` type, which
|
||||||
@ -561,8 +474,49 @@ impl Iterator for IntoIter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WalkDirIterator for IntoIter {
|
impl IntoIter {
|
||||||
fn skip_current_dir(&mut self) {
|
/// Skips the current directory.
|
||||||
|
///
|
||||||
|
/// This causes the iterator to stop traversing the contents of the least
|
||||||
|
/// recently yielded directory. This means any remaining entries in that
|
||||||
|
/// directory will be skipped (including sub-directories).
|
||||||
|
///
|
||||||
|
/// Note that the ergonomics of this method are questionable since it
|
||||||
|
/// borrows the iterator mutably. Namely, you must write out the looping
|
||||||
|
/// condition manually. For example, to skip hidden entries efficiently on
|
||||||
|
/// unix systems:
|
||||||
|
///
|
||||||
|
/// ```rust,no_run
|
||||||
|
/// use walkdir::{DirEntry, WalkDir};
|
||||||
|
///
|
||||||
|
/// fn is_hidden(entry: &DirEntry) -> bool {
|
||||||
|
/// entry.file_name()
|
||||||
|
/// .to_str()
|
||||||
|
/// .map(|s| s.starts_with("."))
|
||||||
|
/// .unwrap_or(false)
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// let mut it = WalkDir::new("foo").into_iter();
|
||||||
|
/// loop {
|
||||||
|
/// let entry = match it.next() {
|
||||||
|
/// None => break,
|
||||||
|
/// Some(Err(err)) => panic!("ERROR: {}", err),
|
||||||
|
/// Some(Ok(entry)) => entry,
|
||||||
|
/// };
|
||||||
|
/// if is_hidden(&entry) {
|
||||||
|
/// if entry.file_type().is_dir() {
|
||||||
|
/// it.skip_current_dir();
|
||||||
|
/// }
|
||||||
|
/// continue;
|
||||||
|
/// }
|
||||||
|
/// println!("{}", entry.path().display());
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// You may find it more convenient to use the `filter_entry` iterator
|
||||||
|
/// adapter. (See its documentation for the same example functionality as
|
||||||
|
/// above.)
|
||||||
|
pub fn skip_current_dir(&mut self) {
|
||||||
if !self.stack_list.is_empty() {
|
if !self.stack_list.is_empty() {
|
||||||
self.stack_list.pop();
|
self.stack_list.pop();
|
||||||
}
|
}
|
||||||
@ -570,9 +524,46 @@ impl WalkDirIterator for IntoIter {
|
|||||||
self.stack_path.pop();
|
self.stack_path.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl IntoIter {
|
/// Yields only entries which satisfy the given predicate and skips
|
||||||
|
/// descending into directories that do not satisfy the given predicate.
|
||||||
|
///
|
||||||
|
/// The predicate is applied to all entries. If the predicate is
|
||||||
|
/// true, iteration carries on as normal. If the predicate is false, the
|
||||||
|
/// entry is ignored and if it is a directory, it is not descended into.
|
||||||
|
///
|
||||||
|
/// This is often more convenient to use than `skip_current_dir`. For
|
||||||
|
/// example, to skip hidden files and directories efficiently on unix
|
||||||
|
/// systems:
|
||||||
|
///
|
||||||
|
/// ```rust,no_run
|
||||||
|
/// use walkdir::{DirEntry, WalkDir};
|
||||||
|
///
|
||||||
|
/// fn is_hidden(entry: &DirEntry) -> bool {
|
||||||
|
/// entry.file_name()
|
||||||
|
/// .to_str()
|
||||||
|
/// .map(|s| s.starts_with("."))
|
||||||
|
/// .unwrap_or(false)
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// for entry in WalkDir::new("foo")
|
||||||
|
/// .into_iter()
|
||||||
|
/// .filter_entry(|e| !is_hidden(e)) {
|
||||||
|
/// let entry = entry.unwrap();
|
||||||
|
/// println!("{}", entry.path().display());
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Note that the iterator will still yield errors for reading entries that
|
||||||
|
/// may not satisfy the predicate.
|
||||||
|
///
|
||||||
|
/// Note that entries skipped with `min_depth` and `max_depth` are not
|
||||||
|
/// passed to this predicate.
|
||||||
|
pub fn filter_entry<P>(self, predicate: P) -> FilterEntry<Self, P>
|
||||||
|
where Self: Sized, P: FnMut(&DirEntry) -> bool {
|
||||||
|
FilterEntry { it: self, predicate: predicate }
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_entry(
|
fn handle_entry(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut dent: DirEntry,
|
mut dent: DirEntry,
|
||||||
@ -890,9 +881,8 @@ pub struct FilterEntry<I, P> {
|
|||||||
predicate: P,
|
predicate: P,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, P> Iterator for FilterEntry<I, P>
|
impl<P> Iterator for FilterEntry<IntoIter, P>
|
||||||
where I: WalkDirIterator<Item=Result<DirEntry>>,
|
where P: FnMut(&DirEntry) -> bool {
|
||||||
P: FnMut(&DirEntry) -> bool {
|
|
||||||
type Item = Result<DirEntry>;
|
type Item = Result<DirEntry>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Result<DirEntry>> {
|
fn next(&mut self) -> Option<Result<DirEntry>> {
|
||||||
@ -912,10 +902,88 @@ impl<I, P> Iterator for FilterEntry<I, P>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, P> WalkDirIterator for FilterEntry<I, P>
|
impl<P> FilterEntry<IntoIter, P>
|
||||||
where I: WalkDirIterator<Item=Result<DirEntry>>,
|
where P: FnMut(&DirEntry) -> bool {
|
||||||
P: FnMut(&DirEntry) -> bool {
|
/// Yields only entries which satisfy the given predicate and skips
|
||||||
fn skip_current_dir(&mut self) {
|
/// descending into directories that do not satisfy the given predicate.
|
||||||
|
///
|
||||||
|
/// The predicate is applied to all entries. If the predicate is
|
||||||
|
/// true, iteration carries on as normal. If the predicate is false, the
|
||||||
|
/// entry is ignored and if it is a directory, it is not descended into.
|
||||||
|
///
|
||||||
|
/// This is often more convenient to use than `skip_current_dir`. For
|
||||||
|
/// example, to skip hidden files and directories efficiently on unix
|
||||||
|
/// systems:
|
||||||
|
///
|
||||||
|
/// ```rust,no_run
|
||||||
|
/// use walkdir::{DirEntry, WalkDir};
|
||||||
|
///
|
||||||
|
/// fn is_hidden(entry: &DirEntry) -> bool {
|
||||||
|
/// entry.file_name()
|
||||||
|
/// .to_str()
|
||||||
|
/// .map(|s| s.starts_with("."))
|
||||||
|
/// .unwrap_or(false)
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// for entry in WalkDir::new("foo")
|
||||||
|
/// .into_iter()
|
||||||
|
/// .filter_entry(|e| !is_hidden(e)) {
|
||||||
|
/// let entry = entry.unwrap();
|
||||||
|
/// println!("{}", entry.path().display());
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Note that the iterator will still yield errors for reading entries that
|
||||||
|
/// may not satisfy the predicate.
|
||||||
|
///
|
||||||
|
/// Note that entries skipped with `min_depth` and `max_depth` are not
|
||||||
|
/// passed to this predicate.
|
||||||
|
pub fn filter_entry(self, predicate: P) -> FilterEntry<Self, P> {
|
||||||
|
FilterEntry { it: self, predicate: predicate }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Skips the current directory.
|
||||||
|
///
|
||||||
|
/// This causes the iterator to stop traversing the contents of the least
|
||||||
|
/// recently yielded directory. This means any remaining entries in that
|
||||||
|
/// directory will be skipped (including sub-directories).
|
||||||
|
///
|
||||||
|
/// Note that the ergonomics of this method are questionable since it
|
||||||
|
/// borrows the iterator mutably. Namely, you must write out the looping
|
||||||
|
/// condition manually. For example, to skip hidden entries efficiently on
|
||||||
|
/// unix systems:
|
||||||
|
///
|
||||||
|
/// ```rust,no_run
|
||||||
|
/// use walkdir::{DirEntry, WalkDir};
|
||||||
|
///
|
||||||
|
/// fn is_hidden(entry: &DirEntry) -> bool {
|
||||||
|
/// entry.file_name()
|
||||||
|
/// .to_str()
|
||||||
|
/// .map(|s| s.starts_with("."))
|
||||||
|
/// .unwrap_or(false)
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// let mut it = WalkDir::new("foo").into_iter();
|
||||||
|
/// loop {
|
||||||
|
/// let entry = match it.next() {
|
||||||
|
/// None => break,
|
||||||
|
/// Some(Err(err)) => panic!("ERROR: {}", err),
|
||||||
|
/// Some(Ok(entry)) => entry,
|
||||||
|
/// };
|
||||||
|
/// if is_hidden(&entry) {
|
||||||
|
/// if entry.file_type().is_dir() {
|
||||||
|
/// it.skip_current_dir();
|
||||||
|
/// }
|
||||||
|
/// continue;
|
||||||
|
/// }
|
||||||
|
/// println!("{}", entry.path().display());
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// You may find it more convenient to use the `filter_entry` iterator
|
||||||
|
/// adapter. (See its documentation for the same example functionality as
|
||||||
|
/// above.)
|
||||||
|
pub fn skip_current_dir(&mut self) {
|
||||||
self.it.skip_current_dir();
|
self.it.skip_current_dir();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ use std::collections::HashMap;
|
|||||||
use quickcheck::{Arbitrary, Gen, QuickCheck, StdGen};
|
use quickcheck::{Arbitrary, Gen, QuickCheck, StdGen};
|
||||||
use rand::{self, Rng};
|
use rand::{self, Rng};
|
||||||
|
|
||||||
use super::{DirEntry, WalkDir, WalkDirIterator, IntoIter, Error, ErrorInner};
|
use super::{DirEntry, WalkDir, IntoIter, Error, ErrorInner};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||||
enum Tree {
|
enum Tree {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user