bitsy-parser 0.70.2

A parser and utilities for working with Bitsy game data
Documentation
use crate::colour::Colour;

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Palette {
    pub id: String,
    pub name: Option<String>,
    pub colours: Vec<Colour>,
}

impl From<String> for Palette {
    #[inline]
    fn from(string: String) -> Palette {
        let lines: Vec<&str> = string.lines().collect();

        let id = lines[0].replace("PAL ", "");

        let name = match lines[1].starts_with("NAME") {
            true => Some(lines[1].replace("NAME ", "").to_string()),
            false => None,
        };

        let colour_start_index = if name.is_some() { 2 } else { 1 };

        let colours = lines[colour_start_index..]
            .iter()
            .map(|&line| Colour::from(line.to_string()))
            .collect();

        Palette { id, name, colours }
    }
}

impl ToString for Palette {
    #[inline]
    fn to_string(&self) -> String {
        let name = if self.name.as_ref().is_some() {
            format!("NAME {}\n", self.name.as_ref().unwrap())
        } else {
            "".to_string()
        };

        let mut colours = String::new();
        for colour in &self.colours {
            colours.push_str(&format!("{}\n", colour.to_string()));
        }
        colours.pop();

        format!("PAL {}\n{}{}", self.id, name, colours)
    }
}

#[cfg(test)]
mod test {
    use crate::colour::Colour;
    use crate::palette::Palette;

    #[test]
    fn test_palette_from_string() {
        let output = Palette::from("PAL 1\nNAME lamplight\n45,45,59\n66,60,39\n140,94,1".to_string());

        let expected = Palette {
            id: "1".to_string(),
            name: Some("lamplight".to_string()),
            colours: vec![
                Colour {
                    red: 45,
                    green: 45,
                    blue: 59,
                },
                Colour {
                    red: 66,
                    green: 60,
                    blue: 39,
                },
                Colour {
                    red: 140,
                    green: 94,
                    blue: 1,
                },
            ],
        };

        assert_eq!(output, expected);
    }

    #[test]
    fn test_palette_from_string_no_name() {
        let output = Palette::from("PAL 9\n45,45,59\n66,60,39\n140,94,1".to_string());

        let expected = Palette {
            id: "9".to_string(),
            name: None,
            colours: vec![
                Colour {
                    red: 45,
                    green: 45,
                    blue: 59,
                },
                Colour {
                    red: 66,
                    green: 60,
                    blue: 39,
                },
                Colour {
                    red: 140,
                    green: 94,
                    blue: 1,
                },
            ],
        };

        assert_eq!(output, expected);
    }

    #[test]
    fn test_palette_to_string() {
        let output = Palette {
            id: "g".to_string(),
            name: Some("moss".to_string()),
            colours: vec![
                Colour {
                    red: 1,
                    green: 2,
                    blue: 3,
                },
                Colour {
                    red: 255,
                    green: 254,
                    blue: 253,
                },
                Colour {
                    red: 126,
                    green: 127,
                    blue: 128,
                },
            ],
        }
            .to_string();
        let expected = "PAL g\nNAME moss\n1,2,3\n255,254,253\n126,127,128".to_string();
        assert_eq!(output, expected);
    }
}