StructA
implements From<StructB>
, and StructB
implements From<S>
.
How can I generically implement a 'shortcut' Into<StructA> for S
or From<S> for StructA
?
If this is a bad idea, please do tell. But kindly explain how to do it anyway for the sake of learning.
Here's my attempt:
struct StructA {
f: StructB
}
struct StructB {
g: i32
}
impl From<StructB> for StructA {
fn from(v: StructB) -> Self {
Self {
f: v
}
}
}
impl From<i32> for StructB {
fn from(v: i32) -> Self {
Self {
g: v
}
}
}
impl<T: Into<StructA>, S: Into<T>> Into<StructA> for S {
fn into(self) -> StructA {
let i: T = self.into();
i.into()
}
}
The error I get is the type parameter 'T' is not constrained by the impl trait, self type, or predicates
.
I don't understand it. Isn't T
constrained by Into<StructA>
?
The error message basically states that the compiler has no way to infer what type T
may be – it basically has to figure out whether any type T
exists such that the given trait bounds T: Into<StructA>, S: Into<T>
are satisfied, and this is not possible in Rust. One problem with this is, as stated in the comments, that there might be multiple types T
satisfying the trait bounds, in which case the compiler can't determine which one to use.
In addition, the Into
trait already has a blanket implementation in the standard library.
impl<T, U: From<T>> Into<U> for T;
There is no way for the compiler to guarantee that this impl doesn't overlap with your blanket impl, which would also make the implementation ambiguous.
I recommend you simply implement From<i32> for StructA
explicitly. If you need many such implementations, macros could be useful.