I'm using anyhow for error handling, and itertools to gives some steroid to my iterators
I am reading a file, line by line, and parsing it. Each line should contains two f64 separated by whitespace. At any point if any kind of parsing fails, I want to return with an error, and add a custom message generated with an error_msg
closure (I want to create the message only if there is an error).
TL; DR:
- How do I convert an
Iterator<Item=Result<T>>
into aResult<Iterator<Item=T>>
? - How do I convert an
Option<T>
into aResult<T, _>
to be able to usewith_context()?
from anyhow?
This works, but it is very verbose and error prone:
let mut iter = line.split_whitespace();
let lat: f64 = iter
.next()
.with_context(err_msg)?
.parse()
.with_context(err_msg)?;
let lon: f64 = iter
.next()
.with_context(err_msg)?
.parse()
.with_context(err_msg)?;
// assert that there is no more items on that line
assert_eq!(iter.next(), None, "{}", err_msg());
I would like to use the much more concise and less error prone collect_tuple()
from itertools instead:
let (lat, lon): (f64, f64) = line
.split_whitespace()
.map(|x| x.parse().unwrap())
.collect_tuple()
.unwrap();
This works, and it's much cleaner, but I lost my nice error message. How can I add them back?
- I tried something alike this to be able to to convert the
Iterator<Result<T>>
into aResult<Iterator<T>>
to be able to use the try operator, without success.
iterator
.map(|x| x.parse())
.collect::<Result<Iterator<Item=(f64, f64)>>>()?
- I could use
ok_or_else
to unwrap the option returned bycollect_tuple()
(in case there not exactly two numbers in the line), but I don't know how to convert the string returned byerr_msg
into anErr
. I tried to dook_or_else(|| Err(err_msg()))
but I got this error:
110 | .ok_or_else(|| Err(err_msg()))?;
| ^ the trait `std::error::Error` is not implemented for `std::result::Result<_, std::string::String>`
|
= note: required because of the requirements on the impl of `std::convert::From<std::result::Result<_, std::string::String>>` for `anyhow::Error`
= note: required by `std::convert::From::from`