I have code like this:
let things = vec![/* ...*/]; // e.g. Vec<String>
things
.map(|thing| {
let a = try!(do_stuff(thing));
Ok(other_stuff(a))
})
.filter(|thing_result| match *thing_result {
Err(e) => true,
Ok(a) => check(a),
})
.map(|thing_result| {
let a = try!(thing_result);
// do stuff
b
})
.collect::<Result<Vec<_>, _>>()
In terms of semantics, I want to stop processing after the first error.
The above code works, but it feels quite cumbersome. Is there a better way? I've looked through the docs for something like filter_if_ok
, but I haven't found anything.
I am aware of collect::<Result<Vec<_>, _>>
, and it works great. I'm specifically trying to eliminate the following boilerplate:
- In the filter's closure, I have to use
match
onthing_result
. I feel like this should just be a one-liner, e.g..filter_if_ok(|thing| check(a))
. - Every time I use
map
, I have to include an extra statementlet a = try!(thing_result);
in order to deal with the possibility of anErr
. Again, I feel like this could be abstracted away into.map_if_ok(|thing| ...)
.
Is there another approach I can use to get this level of conciseness, or do I just need to tough it out?
rust some.iter().map(|x| fallible(x)).try_collect();
– Oblation