BurntSushi / walkdir

Rust library for walking directories recursively.
The Unlicense
1.24k stars 107 forks source link

How find path relative to walkdir-root #5

Closed purew closed 8 years ago

purew commented 8 years ago

Hello,

I'm looking for an easy way to find the relative path between dir given to WalkDir::new and found files. The docstring below from DirEntry says that the path() is formed by joining the WalkDir::new-path with the relative path I'm interested in, below called "file name of this entry". But the file_name() logically only returns the filename, not the dirs between...

fn path(&self) -> &Path[−]

The full path that this entry represents.

The full path is created by joining the parents of this entry up to the root initially given to WalkDir::new with the file name of this entry.

purew commented 8 years ago

Actually, I would prefer if the DirEntry's returned the relative path, leaving it up to the user to build the absolute path if required. Python's os.walk works like this. What are your thoughts on this?

BurntSushi commented 8 years ago

@PureW Perhaps I'm missing something, but it seems easy enough to get what you want with Path::strip_prefix, no? For example:

let root = "/foo/bar/baz".to_owned();
for ent in WalkDir::new(&root) {
    let ent = ent.unwrap();
    println!("relative path: {}", ent.path().strip_prefix(&root).unwrap());
}

Apologies if there are any errors, the above code was not checked by a compiler.

purew commented 8 years ago

Aye, I found strip_prefix shortly after writing this. It just felt a little unnecessary to form the absolute path and then deconstruct it again, compared to returning relative path and joining with root if absolute path if desired. I wonder if not the relative path is the more common usecase...

BurntSushi commented 8 years ago

@PureW It's not a decision that is completely under the control of this library. WalkDir builds on the shallow directory iterator from std::fs, which is where the contract comes from: http://doc.rust-lang.org/std/fs/struct.DirEntry.html --- WalkDir essentially just re-exports that value.

I note that strip_prefix should be extremely cheap from a performance perspective. In particular, it doesn't require any allocations.

I have no idea what the more common use case is. Even if we did add a new relative_path method, for example, its implementation would be exactly what I proposed: it would just use strip_prefix internally because it gets the full path from the underlying std::fs::DirEntry. In other words, the implementation wouldn't become any more efficient unfortunately. To me, that suggests there's little utility in adding it, although, it could be nice from a convenience point-of-view. I would prefer not to add such things and keep the API small, at least for now.

purew commented 8 years ago

I agree then.

I was just initially a bit surprised after having used python's os.walk and a similar lib for C that produced paths relative to the start of the "walk".