WalkDir and ignoring the input dir

Is there a way to get WalkDir to return only the directory entries within the directory it is asked to scan, and leaving out the prefix/input directory?

I.e. given the directory tree:

/wherever/someplace/this/is
/wherever/someplace/this/is/the
/wherever/someplace/this/interesting
/wherever/someplace/this/interesting/part

And you only want to return:

is
is/the
interesting
interesting/part

How would you go about doing that?

In a single threaded application I set the current directory to the root directory and scan ., then I just remove the first two "characters" (yes, I know). But now I need to do this in a multithreaded application, and I don't want to have to put the current directory behind a Mutex.

I'm doing this this:

use std::path::Path;
use walkdir::WalkDir;

fn main() {
  let p = Path::new("/wherever/someplace/this");
  for entry in WalkDir::new(p) {
    let entry = entry.unwrap();
    println!("{:?}", entry.path());
    println!("{:?}", entry.path().strip_prefix(p).unwrap());
  }
}

But I'm concerned that this may have some weird side-effects. Or is the returned DirEntry guaranteed to return a 1:1 clone of the input directory as prefix?

@BurntSushi ?

You don't need a Mutex to share immutable things. An Arc is enough.

Sorry, I should have been clearer: The Mutex here would be to protect a resource (the process' cwd in this case). In the case where I switch directory and scan starting from . I need to protect the cwd so that two threads don't try to change directory at the same time.

(That whole situation is what I'm trying to avoid by stripping the prefix, but I want to make sure there are no side-effects in doing so).

Stripping the prefix should be fine.

1 Like

The specific case I'm worried about is for instance on Windows there's those weird \\?\ prefixes, but I guess also magic symlinks and such. I'm concerned that these, may or may not, now or in the future, be preprocessed away from the results. (Because conceptually it would be perfectly okay to do so).

In terms of Rust features, I'm wondering if stripping the prefix is a stable or unstable operation. :slight_smile:

The documentation for DirEntry::path says

The full path is created by joining the original path to read_dir with the filename of this entry.

I don't know exactly how walkdir works but I'd infer it's just extending read_dir by calling it iteratively on the .path()

1 Like

You can split Path into Components and deal with Windows UNC and others that way: https://doc.rust-lang.org/std/path/struct.PrefixComponent.html

If your only goal is to simplify the Path if it is a subdirectory of a current Path, removing the prefix should work fine, assuming both paths are normalised the same way (including capital letters). Hopefully the normalisation takes care of the old Windows' 8.3 shortened path representation.

1 Like