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?
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),
)
}
}