Skip to content

Commit

Permalink
Fix bug when max_depth was set to 0
Browse files Browse the repository at this point in the history
  • Loading branch information
jessegrosjean committed Feb 12, 2019
1 parent 331a896 commit 29c035e
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 35 deletions.
51 changes: 21 additions & 30 deletions src/core/dir_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,18 @@ pub struct DirEntry {
/// is set.
pub metadata: Option<Result<Metadata>>,
/// [`ReadDirSpec`](struct.ReadDirSpec.html) used for reading this entry's
/// content. This is automatically set for directory entries. The
/// content entries. This is automatically set for directories. The
/// [`process_entries`](struct.WalkDir.html#method.process_entries) callback
/// may set this field to `None` to skip reading the contents of this
/// particular directory.
pub content_spec: Option<Arc<ReadDirSpec>>,
/// If `fs::read_dir` generates an error when reading this entry's content
/// then that error is stored here.
/// entries then that error is stored here.
pub content_error: Option<Error>,
/// [`ReadDirSpec`](struct.ReadDirSpec.html) used by this entry's parent to
/// read this entry.
pub parent_spec: Option<Arc<ReadDirSpec>>,
/// read this entry. If this is the root entry then depth value of this parent
/// spec will be `0` even though it should logically be `-1`.
pub parent_spec: Arc<ReadDirSpec>,
}

impl DirEntry {
Expand All @@ -45,7 +46,7 @@ impl DirEntry {
file_name: OsString,
file_type: Result<FileType>,
metadata: Option<Result<Metadata>>,
parent_spec: Option<Arc<ReadDirSpec>>,
parent_spec: Arc<ReadDirSpec>,
content_spec: Option<Arc<ReadDirSpec>>,
) -> DirEntry {
DirEntry {
Expand All @@ -59,34 +60,12 @@ impl DirEntry {
}
}

/// Path to the file/directory represented by this entry.
///
/// The path is created by joining `parent_path` with `file_name`.
pub fn path(&self) -> PathBuf {
let mut path = match self.parent_spec.as_ref() {
Some(parent_spec) => parent_spec.path.to_path_buf(),
None => PathBuf::from(""),
};
path.push(&self.file_name);
path
}

/// Reference to the path of the directory containing this entry.
pub fn parent_path(&self) -> Option<&Path> {
self
.parent_spec
.as_ref()
.map(|parent_spec| parent_spec.path.as_ref())
}

// Should use std::convert::TryFrom when stable
pub(crate) fn try_from(path: &Path) -> Result<DirEntry> {
pub(crate) fn new_root_with_path(path: &Path) -> Result<DirEntry> {
let metadata = fs::metadata(path)?;
let root_name = OsString::from("/");
let file_name = path.file_name().unwrap_or(&root_name);
let parent_spec = path
.parent()
.map(|parent| Arc::new(ReadDirSpec::new(parent.to_path_buf(), 0, None)));
let parent_path = path.parent().map(|p| p.to_path_buf()).unwrap_or_default();
let parent_spec = Arc::new(ReadDirSpec::new(parent_path, 0, None));

Ok(DirEntry::new(
0,
Expand All @@ -97,4 +76,16 @@ impl DirEntry {
None,
))
}

/// Path to the file/directory represented by this entry.
///
/// The path is created by joining `parent_path` with `file_name`.
pub fn path(&self) -> PathBuf {
self.parent_spec.path.join(&self.file_name)
}

/// Reference to the path of the directory containing this entry.
pub fn parent_path(&self) -> &Path {
&self.parent_spec.path
}
}
2 changes: 1 addition & 1 deletion src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ where
F: Fn(Arc<ReadDirSpec>) -> Result<ReadDir> + Send + Sync + Clone + 'static,
{
let path = path.into();
let root_entry_result = DirEntry::try_from(&path);
let root_entry_result = DirEntry::new_root_with_path(&path);
let ordered_read_dir_spec = root_entry_result.as_ref().ok().and_then(|root_entry| {
if root_entry.file_type.as_ref().ok()?.is_dir() {
let read_dir_spec = Arc::new(ReadDirSpec::new(path, 0, None));
Expand Down
7 changes: 6 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@ impl IntoIterator for WalkDir {

core::walk(&self.root, num_threads, move |read_dir_spec| {
let depth = read_dir_spec.depth + 1;

if depth > max_depth {
return Ok(ReadDir::new(Vec::new()));
}

let mut dir_entry_results: Vec<_> = fs::read_dir(&read_dir_spec.path)?
.filter_map(|dir_entry_result| {
let dir_entry = match dir_entry_result {
Expand Down Expand Up @@ -178,7 +183,7 @@ impl IntoIterator for WalkDir {
file_name,
file_type,
metadata,
Some(read_dir_spec.clone()),
read_dir_spec.clone(),
content_spec,
)))
})
Expand Down
17 changes: 14 additions & 3 deletions tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,13 @@ fn see_hidden_files() {
}

#[test]
fn max_depth() {
fn max_depth_0() {
let paths = local_paths(WalkDir::new(test_dir()).max_depth(0).sort(true));
assert!(paths == vec![" (0)",]);
}

#[test]
fn max_depth_1() {
let paths = local_paths(WalkDir::new(test_dir()).max_depth(1).sort(true));
assert!(
paths
Expand All @@ -114,6 +120,11 @@ fn walk_file() {

#[test]
fn walk_root() {
let mut iter = walkdir::WalkDir::new("/").max_depth(1).into_iter();
assert!(iter.next().unwrap().unwrap().file_name() == "/");
let paths: Vec<_> = WalkDir::new("/")
.max_depth(1)
.sort(true)
.into_iter()
.filter_map(|each| Some(each.ok()?.path()))
.collect();
assert!(paths.first().unwrap().to_str().unwrap() == "/");
}

0 comments on commit 29c035e

Please sign in to comment.