gem/rgb/traits/
rgb_color.rs

1use crate::rgb::{HasBlue, HasGreen, HasRed};
2
3/// A trait for types that have red, green, and blue components.
4pub trait RgbColor: Sized + Default + HasRed + HasGreen + HasBlue {
5    /// Creates a new color with the given red, green, and blue components.
6    ///
7    /// How components are represented, including possible clamping or conversion, is determined by
8    /// the implementation.
9    ///
10    /// This method is provided as a convenience to create _any_ [`RgbColor`] type; most types will
11    /// have their own dedicated constructor methods that may be more efficient and specific. For
12    /// example [`Rgb888::from_rgb`][], [`Rgb565::from_rgb`][], etc.
13    ///
14    /// [`Rgb888::from_rgb`]: crate::rgb::Rgb888::from_rgb
15    /// [`Rgb565::from_rgb`]: crate::rgb::Rgb565::from_rgb
16    #[must_use]
17    fn from_rgb(
18        red: <Self as crate::rgb::HasRed>::Component,
19        green: <Self as crate::rgb::HasGreen>::Component,
20        blue: <Self as crate::rgb::HasBlue>::Component,
21    ) -> Self {
22        let mut color = Self::default();
23        color.set_red(red);
24        color.set_green(green);
25        color.set_blue(blue);
26        color
27    }
28
29    /// Returns the inner representation of the color as a tuple of red, green, and blue components.
30    #[must_use]
31    fn into_rgb(
32        self,
33    ) -> (
34        <Self as crate::rgb::HasRed>::Component,
35        <Self as crate::rgb::HasGreen>::Component,
36        <Self as crate::rgb::HasBlue>::Component,
37    ) {
38        (self.red(), self.green(), self.blue())
39    }
40}
41
42impl<T> RgbColor for T where T: HasRed + HasGreen + HasBlue + Default + Sized {}
43
44#[cfg(test)]
45mod tests {
46    use crate::rgb::{HasBlue, HasGreen, HasRed};
47
48    #[test]
49    fn rgb_color_trait() {
50        use crate::rgb::{Rgb888, RgbColor};
51
52        let color: Rgb888 = RgbColor::from_rgb(255, 0, 0);
53        assert_eq!(color.red(), 255);
54        assert_eq!(color.green(), 0);
55        assert_eq!(color.blue(), 0);
56
57        let (r, g, b) = color.into_rgb();
58        assert_eq!(r, 255);
59        assert_eq!(g, 0);
60        assert_eq!(b, 0);
61    }
62}