graphics_style/styles/color/
convert.rs

1use super::*;
2
3impl From<(u8, u8, u8)> for Color {
4    fn from(c: (u8, u8, u8)) -> Self {
5        Self::new(c.0, c.1, c.2, 255)
6    }
7}
8
9impl From<[u8; 3]> for Color {
10    fn from(c: [u8; 3]) -> Self {
11        Self::new(c[0], c[1], c[2], 255)
12    }
13}
14
15impl From<(u8, u8, u8, u8)> for Color {
16    fn from(c: (u8, u8, u8, u8)) -> Self {
17        Self::new(c.0, c.1, c.2, c.3)
18    }
19}
20
21impl From<[u8; 4]> for Color {
22    fn from(c: [u8; 4]) -> Self {
23        Self::new(c[0], c[1], c[2], c[3])
24    }
25}
26
27impl From<(f32, f32, f32)> for Color {
28    fn from(c: (f32, f32, f32)) -> Self {
29        Self::new((c.0 * 255.0) as u8, (c.1 * 255.0) as u8, (c.2 * 255.0) as u8, 255)
30    }
31}
32
33impl From<(f32, f32, f32, f32)> for Color {
34    fn from(c: (f32, f32, f32, f32)) -> Self {
35        Self::new((c.0 * 255.0) as u8, (c.1 * 255.0) as u8, (c.2 * 255.0) as u8, (c.3 * 255.0) as u8)
36    }
37}
38
39impl From<Color> for u32 {
40    fn from(c: Color) -> Self {
41        let (r, g, b, a) = c.view();
42        u32::from_le_bytes([r, g, b, a])
43    }
44}
45
46impl From<u32> for Color {
47    fn from(c: u32) -> Self {
48        let [r, g, b, a] = c.to_le_bytes();
49        Self::new(r, g, b, a)
50    }
51}
52
53fn hex_digit(c: &u8) -> Result<u8> {
54    match c {
55        b'0'..=b'9' => Ok(c - b'0'),
56        b'A'..=b'F' => Ok(c - b'A' + 10),
57        b'a'..=b'f' => Ok(c - b'a' + 10),
58        _ => parse_error!("{} does not a valid hex character", c),
59    }
60}
61
62impl FromStr for Color {
63    type Err = GraphicsError;
64
65    fn from_str(s: &str) -> Result<Self> {
66        if !s.starts_with("#") {
67            return parse_error!("{} does not a valid hex color string", s);
68        }
69        let this = match &s[1..].as_bytes() {
70            [c1, c2] => {
71                let c = hex_digit(c1)? * 16 + hex_digit(c2)?;
72                Color::new(c, c, c, 255)
73            }
74            [r, g, b] => Color::new(
75                //
76                hex_digit(r)? * 17,
77                hex_digit(g)? * 17,
78                hex_digit(b)? * 17,
79                255,
80            ),
81            [r, g, b, a] => Color::new(
82                //
83                hex_digit(r)? * 17,
84                hex_digit(g)? * 17,
85                hex_digit(b)? * 17,
86                hex_digit(a)? * 17,
87            ),
88            [r1, r2, g1, g2, b1, b2] => Color::new(
89                hex_digit(r1)? * 16 + hex_digit(r2)?,
90                hex_digit(g1)? * 16 + hex_digit(g2)?,
91                hex_digit(b1)? * 16 + hex_digit(b2)?,
92                255,
93            ),
94            [r1, r2, g1, g2, b1, b2, a1, a2] => Color::new(
95                hex_digit(r1)? * 16 + hex_digit(r2)?,
96                hex_digit(g1)? * 16 + hex_digit(g2)?,
97                hex_digit(b1)? * 16 + hex_digit(b2)?,
98                hex_digit(a1)? * 16 + hex_digit(a2)?,
99            ),
100            _ => return parse_error!("Hex color string length must be 2, 3, 4, 6, 8."),
101        };
102        Ok(this)
103    }
104}