1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
//! Everything related to the color management in the library.

use image::Rgb;

mod palette_color_provider;
mod random_color_provider;

pub use palette_color_provider::*;
pub use random_color_provider::*;

pub trait ColorProvider {
    fn random_color(&mut self) -> Rgb<u8>;
}

pub fn color_from_hex(hex: &str) -> Result<Rgb<u8>, String> {
    let mut hex = hex;
    if hex.starts_with('#') {
        hex = &hex[1..hex.len()];
    }
    if hex.len() != 6 {
        return Err(format!("Not a color: '{}'", hex));
    }

    let r = &hex[0..=1];
    let g = &hex[2..=3];
    let b = &hex[4..=5];

    let r = match u8::from_str_radix(r, 16) {
        Ok(v) => v,
        Err(e) => return Err(e.to_string()),
    };
    let g = match u8::from_str_radix(g, 16) {
        Ok(v) => v,
        Err(e) => return Err(e.to_string()),
    };
    let b = match u8::from_str_radix(b, 16) {
        Ok(v) => v,
        Err(e) => return Err(e.to_string()),
    };

    Ok(Rgb([r, g, b]))
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn color_from_hex() {
        assert_eq!(
            Rgb([239, 89, 123]),
            super::color_from_hex("EF597B").unwrap()
        );
    }

    #[test]
    fn color_from_hex_not_a_color() {
        let c = super::color_from_hex("foobar");
        assert!(c.is_err());

        let c = super::color_from_hex("foo");
        assert!(c.is_err());
    }
}