bitsy_parser/
colour.rs

1#[derive(Clone, Debug, Eq, PartialEq)]
2pub struct Colour {
3    pub red: u8,
4    pub green: u8,
5    pub blue: u8,
6}
7
8impl Colour {
9    pub fn from(string: &str) -> Result<Colour, crate::Error> {
10        let values: Vec<&str> = string.trim_matches(',').split(',').collect();
11
12        if values.len() != 3 {
13            return Err(crate::Error::Colour);
14        }
15
16        let red: u8 = values[0].parse().unwrap_or(0);
17        let green: u8 = values[1].parse().unwrap_or(0);
18        let blue: u8 = values[2].parse().unwrap_or(0);
19
20        Ok(Colour { red, green, blue })
21    }
22
23    pub fn from_hex(hex: &str) -> Result<Colour, crate::Error> {
24        let hex = hex.to_lowercase().trim_start_matches('#').to_string();
25        let rgb = data_encoding::HEXLOWER.decode(hex.as_bytes()).unwrap();
26
27        Ok(Colour { red: rgb[0], green: rgb[1], blue: rgb[2], })
28    }
29}
30
31impl ToString for Colour {
32    fn to_string(&self) -> String {
33        format!("{},{},{}", self.red, self.green, self.blue)
34    }
35}
36
37#[cfg(test)]
38mod test {
39    use crate::Colour;
40
41    #[test]
42    fn colour_from_string() {
43        assert_eq!(
44            Colour::from("0,255,0").unwrap(),
45            Colour { red: 0, green: 255, blue: 0 }
46        );
47    }
48
49    #[test]
50    fn colour_to_string() {
51        assert_eq!(Colour { red: 22, green: 33, blue: 44, }.to_string(), "22,33,44".to_string());
52    }
53
54    #[test]
55    fn colour_missing_value() {
56        assert!(Colour::from("0,0").is_err());
57    }
58
59    #[test]
60    fn colour_ambiguous_value() {
61        assert!(Colour::from("0,0,").is_err());
62    }
63
64    #[test]
65    fn colour_extraneous_value() {
66        assert!(Colour::from("0,0,0,0").is_err());
67    }
68
69    #[test]
70    fn colour_from_hex() {
71        let output = Colour::from_hex("#ffff00").unwrap();
72        let expected = Colour { red: 255, green: 255, blue: 0 };
73        assert_eq!(output, expected);
74    }
75
76    #[test]
77    fn colour_from_hex_upper() {
78        let output = Colour::from_hex("#ABCDEF").unwrap();
79        let expected = Colour { red: 171, green: 205, blue: 239 };
80        assert_eq!(output, expected);
81    }
82}