lighthouse_protocol/utils/
color.rs

1use rand::{prelude::Distribution, distributions::Standard};
2use serde::{Deserialize, Serialize};
3
4/// An RGB color.
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
6pub struct Color {
7    #[serde(rename = "R")]
8    pub red: u8,
9    #[serde(rename = "G")]
10    pub green: u8,
11    #[serde(rename = "B")]
12    pub blue: u8,
13}
14
15impl Color {
16    pub const BLACK: Self = Self { red: 0, green: 0, blue: 0 };
17    pub const GRAY: Self = Self { red: 128, green: 128, blue: 128 };
18    pub const WHITE: Self = Self { red: 255, green: 255, blue: 255 };
19    pub const RED: Self = Self { red: 255, green: 0, blue: 0 };
20    pub const GREEN: Self = Self { red: 0, green: 255, blue: 0 };
21    pub const BLUE: Self = Self { red: 0, green: 0, blue: 255 };
22    pub const YELLOW: Self = Self { red: 255, green: 255, blue: 0 };
23    pub const CYAN: Self = Self { red: 0, green: 255, blue: 255 };
24    pub const MAGENTA: Self = Self { red: 255, green: 0, blue: 255 };
25
26    /// Creates a new color from the given RGB components.
27    pub const fn new(red: u8, green: u8, blue: u8) -> Self {
28        Self { red, green, blue }
29    }
30}
31
32impl From<[u8; 3]> for Color {
33    fn from([red, green, blue]: [u8; 3]) -> Self {
34        Self { red, green, blue }
35    }
36}
37
38impl From<Color> for [u8; 3] {
39    fn from(color: Color) -> [u8; 3] {
40        [color.red, color.green, color.blue]
41    }
42}
43
44impl Distribution<Color> for Standard {
45    fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> Color {
46        Color::new(rng.gen(), rng.gen(), rng.gen())
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use crate::Color;
53
54    #[test]
55    fn to_array() {
56        assert_eq!(<[u8; 3]>::from(Color::BLACK), [0, 0, 0]);
57        assert_eq!(<[u8; 3]>::from(Color::RED), [0xFF, 0, 0]);
58        assert_eq!(<[u8; 3]>::from(Color::GREEN), [0, 0xFF, 0]);
59        assert_eq!(<[u8; 3]>::from(Color::BLUE), [0, 0, 0xFF]);
60        assert_eq!(<[u8; 3]>::from(Color::new(1, 2, 3)), [1, 2, 3]);
61    }
62
63    #[test]
64    fn from_array() {
65        assert_eq!(Color::from([0, 0, 0]), Color::BLACK);
66        assert_eq!(Color::from([0xFF, 0, 0]), Color::RED);
67        assert_eq!(Color::from([0, 0xFF, 0]), Color::GREEN);
68        assert_eq!(Color::from([0, 0, 0xFF]), Color::BLUE);
69        assert_eq!(Color::from([1, 2, 3]), Color::new(1, 2, 3));
70    }
71}