3
\$\begingroup\$

I'm learning Rust and looking for better/cleaner ways to list all file names that do not start with filter, given a pathname as a parameter.

    fn list_files(&self, pathname: &PathBuf, filter: &str) -> Result<Vec<PathBuf>, Error> {
        fs::read_dir(pathname).map(|read_dir| {
            read_dir
                .filter_map(|res| {
                    res.map(|entry| {
                        entry
                            .path()
                            .strip_prefix(pathname)
                            .ok()
                            .map(|path| {
                                if path.starts_with(filter) {
                                    None
                                } else {
                                    Some(path.to_path_buf())
                                }
                            })
                            .flatten()
                    })
                    .ok()
                    .flatten()
                })
                .collect()
        })
    }
\$\endgroup\$
2
\$\begingroup\$

As far as I can tell, you're returning error only in case of read_dir failure. Not sure if anyone ever really needs it, but you could change upmost Some() to Ok(), remove .ok() and fix the signature so that my version works just like yours. Note: the code below wasn't tested. I didn't like nested structure of your function, so I came up with this:

use std::fs;
use std::path::PathBuf;

fn list_files(pathname: &PathBuf, filter: &str) -> Option<Vec<PathBuf>> {
    Some(fs::read_dir(pathname).ok()?
        .filter_map(|entry| {
            Some(
                entry
                    .ok()?
                    .path()
                    .strip_prefix(pathname)
                    .ok()?
                    .to_path_buf(),
            )
        })
        .filter(|path| path.starts_with(filter))
        .collect())
}

Explanation: .ok() maps Result<T, K> to Option<T>, ? operator returns early in case if Option or Result aren't Some()/Ok()

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks a lot! This definitely looks better. \$\endgroup\$ – pt2121 Apr 29 at 13:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.