I need to convert a parse error to my own Error type while returning Result. Simplified, it looks like the following:
enum MyError {
Parse,
...,
}
fn process<R: FromStr>(s: &str) -> Result<(), MyError> {
Ok(s.parse::<R>()?)
}
For above to work From trait should be implemented. This doesn't work:
impl From<std::str::FromStr::Err> for MyError {
fn from(e: std::str::FromStr::Err) -> MyError {
MyError::Parse
}
}
The compiler diagnostics:
help: use fully-qualified syntax: `<Type as std::str::FromStr>::Err`
But I don't know the exact Type
here. The whole point is to allow conversion from all possible errors.
The type FromStr::Err
is an associated type of the FromStr
trait. Every implementation of FromStr
has its own associated type, and this type is completely unconstrained – it could be any type at all. This means you would need a conversion from any type to MyError
to achieve what you want:
impl<T> From<T> for MyError {
fn from(e: T) -> MyError {
MyError::Parse
}
}
However, this implementation is disallowed by the coherence rules – it conflicts with the implementation of From<T>
for any type T
in the standard library. And even if this implementation was allowed, it wouldn't really do what you want – any error type would be converted to MyError::Parse
, not just parse errors.
One possible workaround is to introduce a marker trait for parse error types:
trait ParseError {}
impl<T: ParseError> From<T> for MyError {
fn from(e: T) -> MyError {
MyError::Parse
}
}
You can then implement this marker trait for all parse error types:
impl ParseError for std::str::ParseBoolError {}
impl ParseError for std::num::ParseFloatError {}
impl ParseError for std::num::ParseIntError {}
impl ParseError for std::net::AddrParseError {}
impl ParseError for std::char::ParseCharError {}
If you're discarding the parse error anyway, use map_err
to change the error locally:
fn process<R: FromStr>(s: &str) -> Result<(), MyError> {
let _ = s.parse::<R>().map_err(|_| MyError::Parse)?;
Ok(())
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.