I want to write something like this, but it won't compile due to a mismatch between types:
fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
let val = std::env::args()
.nth(1)
.ok_or("1 arg is expected")
.and_then(std::fs::File::open)
.and_then(serde_yaml::from_reader)?;
}
Because adding a map_err
to every closure seems sluggish and 'boiler platy', I replace it with something like:
fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
let val = serde_yaml::from_reader(std::fs::File::open(
std::env::args().nth(1).ok_or("1 arg is expected")?,
)?)?;
}
The first one feels more natural and reads like English while the second feels sort of backwards.
Should I ditch the and_then
and always use the ?
operator?
If not, is there a way to make result combinator as smooth as the ?
operator?
Should I ditch the and_then and always use the ? operator ?
That’s a personal judgement and only you can answer it.
Is there a way to make result combinator as smooth as the ? operator ?
Frankly speaking no. ?
performs conversions « implicitly » (not really implicitly since it’s very much part of its job, but the conversion doesn’t have to be invoked separately, maybe « tersely »?), and_then
does not. That means when using and_then
, you have to perform these conversions yourself. That seems logical.
You might be able to build a convenience macro for this tho. Or maybe add an extension method or wrapper type which can perform those conversions under the cover.