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\$

    1 Answer 1

    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()

    \$\endgroup\$
    0

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.