iFreilicht
iFreilicht

Reputation: 14524

Implement a trait for generic types that implement a trait for a specific type

The title to this question reads very similar to many related questions, but I haven't found one that discusses this specific issue.

I have a Color type that is very simply defined like this:

pub struct Color {
    red: u8,
    green: u8,
    blue: u8,
}

Now, for interfacing with other libraries and converting to fixed-point numbers, it is useful to be able to convert this to and from any tuples containing arbitrary numeric types.

For this, I use the Az crate. It defines the trait Cast<T> and implements it for a lot of types, allowing me to implement From<(T, T, T)> like so:

use az::Cast;
impl<T: Cast<u8>> From<(T, T, T)> for Color {
    fn from(components: (T, T, T)) -> Color {
        Color {
            red: Cast::cast(components.0),
            green: Cast::cast(components.1),
            blue: Cast::cast(components.2),
        }
    }
}

The trait bound provides me with the Cast::<u8>::cast(T) function, so everything works as expected.

However, I can't seem to find a way to implement the opposite, From<Color>. What I effectively want is this:

impl<T> From<Color> for (T, T, T)
where
    impl Cast<T> for u8 // This doesn't actually work
{
    fn from(color: Color) -> (T, T, T) {
        (
            Cast::cast(color.red),
            Cast::cast(color.green),
            Cast::cast(color.blue),
        )
    }
}

But I can't seem to find a way to actually write this. I checked the docs on bounds, but can't seem to find syntax that allows to express this.

How can I implement this?

Upvotes: 1

Views: 1086

Answers (1)

Aplet123
Aplet123

Reputation: 35560

You're close. Where bounds take on the same syntax as generic bounds:

impl<T> From<Color> for (T, T, T)
where
    // u8 must implement Cast<T>
    u8: Cast<T>,
{
    fn from(color: Color) -> (T, T, T) {
        (
            Cast::cast(color.red),
            Cast::cast(color.green),
            Cast::cast(color.blue),
        )
    }
}

Upvotes: 3

Related Questions