BurntSushi / walkdir

Rust library for walking directories recursively.
The Unlicense
1.21k stars 106 forks source link

Can't filter out directories without also filtering out files in those directories. #158

Closed merehap closed 2 years ago

merehap commented 2 years ago

I'm attempting to list all (non-directory) files recursively in a directory with the following code:

let entries = WalkDir::new("tests/expected_frames").into_iter();
let entries = entries.filter_entry(|entry| !entry.file_type().is_dir());
for entry in entries {
    println!("{}", entry.unwrap().path().display());
}

The result is that nothing is printed (there would be some file paths printed if I had any in "expected_frames", but I only have sub-directories there). It seems that the code that is supposed to only remove directories from the resulting entries is also removing those directories from being recursed.

So this directory structure yields nothing:

tests/expected_frames/1/a.foo tests/expected_frames/1/b.foo tests/expected_frames/2/c.foo

While this directory structure yields the last two lines:

tests/expected_frames/1/a.foo tests/expected_frames/1/b.foo tests/expected_frames/2/c.foo tests/expected_frames/d.foo tests/expected_frames/e.foo

The workaround is to just not use filter_entry, using a regular filter instead:

let entries: Vec<_> = WalkDir::new("tests/expected_frames")
    .into_iter()
    .map(Result::unwrap)
    .filter(|entry| !entry.file_type().is_dir())
    .collect();
for entry in entries {
    println!("{}", entry.path().display());
}

I'm running on linux and this issue occurs for both walkdir 2.3.2 and 2.0.0.

BurntSushi commented 2 years ago

is also removing those directories from being recursed

That is correct and exactly the point of filter_entry. Your work around isn't a work around. It's what you want.