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?