I'm writing an Error enum that represents failure to parse a value obtained from a program's arguments. Initially, it looks like this:
pub enum LoadingError {
NoArg,
CantParse
}
I'd like it to be easily converted from a parsing error. The str::parse function is defined as follows:
pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
FromStr::from_str(self)
}
It seems to me that, if I want to implement the From trait for my enum converting from any FromStr::Err, I would need my function to be generic on the FromStr trait. I tried doing something like this:
pub enum LoadingError<F: FromStr> {
NoArg,
CantParse(F::Err)
}
impl<F: FromStr> From<F::Err> for LoadingError<F> {
fn from(err: F::Err) -> LoadingError<F> {
LoadingError::CantParse(err)
}
}
This, however, does not compile, with this error being returned:
error[E0119]: conflicting implementations of trait `From<LoadingError<_>>` for type `LoadingError<_>`
--> src/main.rs:15:1
|
15 | impl<F: FromStr> From<F::Err> for LoadingError<F> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- impl<T> From<T> for T;
I don't really see how implementations with these two different type signatures would be conflicting, and I couldn't find the definition for impl<T> From<T> for T in Rust's core code.
I've also tried using the thiserror crate, leading me to the same error.
#[derive(Error, Debug)]
pub enum LoadingError<F: FromStr> {
#[error("can't find argument")]
NoArg,
#[error("couldn't parse")]
CantParse(#[from] F::Err)
}
My question is: How can I implement the From trait for my type from any of the many Errs defined by the FromStr trait?
First,
impl<T> From<T> for Tis here.Second, any type can be
FromStr::Err, includingLoadingError. If it was possible to make an impl that only worked on types that were used inFromStr::Err, then it would be possible to change the meaning of your code from outside your crate by writing aFromStrimpl that uses an error type that you assumed wasn't used inFromStr::Err.Instead, you should create
Fromimpls on the actual error types you're looking for, likeParseIntError.Or you can create a method to convert any error into
LoadingErrorand only use it on the result ofparse.You can use this like:
Using a generic on your error type can be problematic, so you may want to store a trait object instead (or use a trait object as the generic).