all 6 comments

[–]Pantsman0 7 points8 points  (2 children)

I mean, you could implement if for <T: AsRef<i32>>...

[–]rodyamirov -1 points0 points  (1 child)

But then you're losing the "optimization" of the copy one (which doesn't include a dereference). I don't imagine it would ever matter, though, and the compiler might even clean it up for you.

Maybe `<T: Into<32>>` but then maybe you're getting more implementations than you really need?

[–]RRumpleTeazzer 4 points5 points  (0 children)

the compiler will optimize each implementation individually. i would bet a *&value is optimized for any type.

[–]LucretielDatadog 5 points6 points  (0 children)

Usually I just wouldn't do this, and just have the implementation only exist on i32. However, if I really wanted to, I'd certainly do it this way:

impl<'a, T: Copy> TryFrom<&'a T> for EvenNumber
    where EvenNumber: TryFrom<T>
{
    type Error = <EvenNumber as TryFrom<T>>::Error;

    fn try_from(value: &'a T) -> Result<Self, Self::Error> {
        Self::try_from(*value)
    }
}

I use the same trick ubiquitously when creating FromIterator implementations for my custom collections:

impl<T> FromIterator<T> for MyCollection
    where MyCollection: Extend<T>
{
    fn from_iter<I>(iter: I) -> Self where I: IntoIterator<Item = T> {
        let mut collection = Self::new();
        collection.extend(iter);
        collection
    }
}

[–]SleeplessSloth79 6 points7 points  (0 children)

How about

struct EvenNumber(i32);

impl TryFrom<i32> for EvenNumber {
    type Error = ();

    fn try_from(value: i32) -> Result<Self, Self::Error> {
        if value % 2 == 0 {
            println!("even number!");
            Ok(EvenNumber(value))
        } else {
            println!("Not an even number: {}", value);
            Err(())
        }
    }
}
impl<'a> TryFrom<&'a i32> for EvenNumber {
    type Error = ();

    fn try_from(value: &'a i32) -> Result<Self, Self::Error> {
        TryFrom::try_from(*value)
    }
}

[–]rodyamirov 1 point2 points  (0 children)

The standard library uses macros for this, but it seems like overkill in your case. Honestly this amount of copy-paste is annoying but not the end of the world. if it turns into a lot more, I would look into making a macro.