bitsy_parser/
palette.rs

1use crate::Colour;
2
3#[derive(Clone, Debug, Eq, PartialEq)]
4pub struct Palette {
5    pub id: String,
6    pub name: Option<String>,
7    pub colours: Vec<Colour>,
8}
9
10impl Palette {
11    pub fn from_str(s: &str) -> Result<(Palette, Vec<crate::Error>), crate::Error> {
12        let mut lines: Vec<&str> = s.lines().collect();
13
14        if lines.is_empty() {
15            return Err(crate::Error::Palette);
16        }
17
18        let mut id = String::new();
19        let mut name = None;
20        let mut colours = Vec::new();
21        let mut warnings = Vec::new();
22
23        while !lines.is_empty() {
24            let line = lines.pop().unwrap();
25
26            if line.starts_with("PAL ") {
27                id = line.replace("PAL ", "");
28            } else if line.starts_with("NAME ") {
29                name = Some(line.replace("NAME ", ""));
30            } else {
31                let result = Colour::from(line);
32                if let Ok(colour) = result {
33                    colours.push(colour)
34                } else {
35                    warnings.push(result.unwrap_err());
36                }
37            }
38        }
39
40        colours.reverse();
41
42        Ok((Palette { id, name, colours }, warnings))
43    }
44}
45
46impl ToString for Palette {
47    fn to_string(&self) -> String {
48        let name = if self.name.as_ref().is_some() {
49            format!("NAME {}\n", self.name.as_ref().unwrap())
50        } else {
51            "".to_string()
52        };
53
54        let mut colours = String::new();
55        for colour in &self.colours {
56            colours.push_str(&format!("{}\n", colour.to_string()));
57        }
58        colours.pop();
59
60        format!("PAL {}\n{}{}", self.id, name, colours)
61    }
62}
63
64#[cfg(test)]
65mod test {
66    use crate::{Colour, Palette};
67
68    #[test]
69    fn palette_from_string() {
70        let (output, _) = Palette::from_str("PAL 1\nNAME lamplight\n45,45,59\n66,60,39\n140,94,1").unwrap();
71
72        let expected = Palette {
73            id: "1".to_string(),
74            name: Some("lamplight".to_string()),
75            colours: vec![
76                Colour {
77                    red: 45,
78                    green: 45,
79                    blue: 59,
80                },
81                Colour {
82                    red: 66,
83                    green: 60,
84                    blue: 39,
85                },
86                Colour {
87                    red: 140,
88                    green: 94,
89                    blue: 1,
90                },
91            ],
92        };
93
94        assert_eq!(output, expected);
95    }
96
97    #[test]
98    fn palette_from_string_no_name() {
99        let (output, _) = Palette::from_str("PAL 9\n45,45,59\n66,60,39\n140,94,1").unwrap();
100
101        let expected = Palette {
102            id: "9".to_string(),
103            name: None,
104            colours: vec![
105                Colour {
106                    red: 45,
107                    green: 45,
108                    blue: 59,
109                },
110                Colour {
111                    red: 66,
112                    green: 60,
113                    blue: 39,
114                },
115                Colour {
116                    red: 140,
117                    green: 94,
118                    blue: 1,
119                },
120            ],
121        };
122
123        assert_eq!(output, expected);
124    }
125
126    #[test]
127    fn palette_to_string() {
128        let output = Palette {
129            id: "g".to_string(),
130            name: Some("moss".to_string()),
131            colours: vec![
132                Colour {
133                    red: 1,
134                    green: 2,
135                    blue: 3,
136                },
137                Colour {
138                    red: 255,
139                    green: 254,
140                    blue: 253,
141                },
142                Colour {
143                    red: 126,
144                    green: 127,
145                    blue: 128,
146                },
147            ],
148        }.to_string();
149
150        let expected = "PAL g\nNAME moss\n1,2,3\n255,254,253\n126,127,128";
151        assert_eq!(output, expected);
152    }
153}