Recursive From for reference on tuple Single< T >( T )?

Viewed 57

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);
}

Playground

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);
}

Playground

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?

1 Answers

In the second case it is not possible to do with single Trait. What is possible to implement a trait for each level:

impl<E> From<&E> for Single<E>
impl<E> From<&&E> for Single<E>
impl<E> From<&&&E> for Single<E>

Although it's not recursive.

Related discussion on Rust forum.

Related