0

I need to map some iterator to parse each value in it, but this mapping should be stopped on any parse error and function contained it should immediately return:

fn some_tasks(elids: String) -> Result<(), String> {
    let ids: Vec<i32> = elids.split(", ").map(|elid| elid.parse::<i32>()?).collect();
    //  ...
    Ok(())
}

This code, of course, doesn't work: compiler thinks that the ? operator should return Err() from closure to map(), not from whole some_tasks():

|     let ids: Vec<i32> = elids.split(", ").map( |elid| elid.parse::<i32>()? ).collect();
|                                                ------                    ^ cannot use the `?` operator in a closure that returns `i32`
|                                                |
|                                                this function should return `Result` or `Option` to accept `?`

Using return operator doesn't help because of similar reasons: compiler thinks it is return from closure to map(), not from whole some_tasks():

fn some_tasks(elids: String) -> Result<(), String> {
    let ids: Vec<i32> = elids.split(", ").map( |elid| {
        let result = elid.parse::<i32>();
        if let Err(e) = result { return Err(e) }
        result.unwrap()
    } ).collect();    //  ...
    Ok(())
}

Of course, I can collect() to Vec<Result<i32, ParseIntError>>, then analyze this vector and return from some_tasks() if it contains any Err(). Or I can add some additional mutable success variable outside of map() and change it from true to false on parsing errors in closure. But both these methods has the save disadvantage: map() will parse ALL elements of iterator before it will be possible to handle such an error outside of map() (in my case it's a lot of excess work).

So my question is: is there any way to break the execution of a map() immediately when an error is detected in closure inside of it?

Ivan Olshansky
  • 889
  • 2
  • 17
  • 23

0 Answers0