There is a trick to define recursive From for reference. Like that:
#[derive(Debug)]
struct Single(i32);
impl From<i32> for Single {
fn from(src: i32) -> Self {
Self(src)
}
}
impl<T> From<&T> for Single
where
T: Clone,
Self: From<T>,
{
fn from(src: &T) -> Self {
From::from((*src).clone())
}
}
fn main() {
let a = Single::from(13);
dbg!(&a);
let a = Single::from(&13);
dbg!(&a);
let a = Single::from(&&13);
dbg!(&a);
}
Problem is that trick does not work if the element of the tuple is a parameter:
struct Single< E >( E );
The reason is conflicting implementation. The best I've got is:
#[derive(Debug)]
struct Single<E>(E);
impl<E> From<E> for Single<E> {
fn from(src: E) -> Self {
Self(src)
}
}
impl<E> From<&E> for Single<E>
where
E: Clone,
Self: From<E>,
{
fn from(src: &E) -> Self {
From::from((*src).clone())
}
}
fn main() {
let a: Single<i32> = Single::from(13);
dbg!(&a);
let a: Single<i32> = Single::from(&13);
dbg!(&a);
let a: Single<i32> = Single::from(&&13);
dbg!(&a);
}
The limitation of the solution is that it does not allow to get From working for deep reference. That does not work:
let a : Single< i32 > = Single::from( &&13 )
It is a minor limitation, but I am curious is it possible to overcome it?