Reputation: 3377
I am trying to create an error type with a blanket From
implementation for any Error
, however since this type is itself an Error
I am getting conflicts:
pub struct ApiError(pub i64, pub String);
impl<T: Error> From<T> for ApiError {
fn from(err: T) -> Self {
Self(500, err.to_string())
}
}
impl Error for ApiError {}
error[E0119]: conflicting implementations of trait `std::convert::From<ApiError>` for type `ApiError`
--> src/lib.rs:5:1
|
5 | impl<T: Error> From<T> for ApiError {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- impl<T> From<T> for T;
I assume it is because of the cycle I have created by implementing Error
on ApiError
. Is it possible to say something like T: Error & not ApiError
and exclude my particular type from this blanket implementation for From
?
If this is not possible I am curious how anyhow seems to do something similar?
Upvotes: 6
Views: 1069
Reputation: 73450
You can not do this in rust, but there is a work around.
Looking at the docs, anyhow::Error
doesn't implement Error
, instead it implemented Deref<Error>
(and similar traits). This allows anyhow::Error
to be silently converted to &Error
.
This means it can now implement From<T:Error>
without running into the conflict you mention.
Upvotes: 6