Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to collect an iterator into a Result?

I currently have the following function:

fn filter_files<P>(input_path: P) -> Result<Vec<DirEntry>, Box<dyn error::Error>> where P: AsRef<Path> {
    fs::read_dir(input_path)?
        .into_iter()
        .filter_map(|res| res.ok())
        .filter(|dir_entry| dir_entry.file_name().to_str().unwrap().starts_with("_x"))
        .collect()
}

Where I am attempting to filter out files that start with _x. I would like to have this function return the filtered Vec<DirEntry> directly instead of having to make a variable. My issue is that I can not get the function signature correct. I am getting an error with

error[E0277]: a value of type `Result<Vec<DirEntry>, Box<dyn std::error::Error>>` cannot be built from an iterator over elements of type `DirEntry`
    --> src/main.rs:18:10
     |
18   |         .collect()
     |          ^^^^^^^ value of type `Result<Vec<DirEntry>, Box<dyn std::error::Error>>` cannot be built from `std::iter::Iterator<Item=DirEntry>`

I am wondering what the correct signature for this function’s return type should be given that the fs::read_dir(...) could return an io::Error I know that I need to be returning a Result type. Is the usage of collect() correct or is this an incorrect usage.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

The error is a little misleading here, you can collect into a Result but only when the iterators items are of type Result<A, E>.

Since you know all your items exist and did not result in an error (your items are of type DirEntry not Result<DirEntry, _>) what you want to do instead is to wrap your known good result in a variant of Result such as Ok:

fn filter_files<P>(input_path: P) -> std::io::Result<Vec<DirEntry>> where P: AsRef<Path> {
    Ok(fs::read_dir(input_path)?
        .into_iter()
        .filter_map(|res| res.ok())
        .filter(|dir_entry| dir_entry.file_name().to_str().unwrap().starts_with("_x"))
        .collect())
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading