I have the following (simplified) code:
pub trait Special {}
pub struct Id(String);
impl From<usize> for Id {
fn from(id: usize) -> Self {
Id(id.to_string())
}
}
impl From<&str> for Id {
fn from(sid: &str) -> Self {
Id(sid.to_string())
}
}
impl From<String> for Id {
fn from(sid: String) -> Self {
Id(sid)
}
}
pub enum SpecialOrId<S> {
Special(S),
Id(Id)
}
impl<S: Special, ID: Into<Id>> From<ID> for SpecialOrId<S> {
fn from(id: ID) -> Self {
Self::Id(id.into())
}
}
impl<S: Special> From<S> for SpecialOrId<S> {
fn from(s: S) -> Self {
Self::Special(s)
}
}
Which produce the error:
error[E0119]: conflicting implementations of trait `std::convert::From<_>` for type `SpecialOrId<_>`
--> src/lib.rs:34:1
|
28 | impl<S: Special, ID: Into<Id>> From<ID> for SpecialOrId<S> {
| ---------------------------------------------------------- first implementation here
...
34 | impl<S: Special> From<S> for SpecialOrId<S> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `SpecialOrId<_>`
From my understanding this is because someone might implement the Special
trait for usize
, &str
or String
which would lead to a conflicting implementation, is it right?
How to solve this? From my research on the web I have seen that implementing a Marker trait for only the allowed types would help this: generics - Conflicting implementations of trait in Rust - Stack Overflow. But I'm not sure to understand how to do that...
Thanks for the help.