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
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
use crate::colour::Colour;

#[derive(Debug, Eq, PartialEq)]
pub struct Palette {
    pub(crate) id: String, // base36 string (why??)
    pub(crate) name: Option<String>,
    pub(crate) colours: Vec<Colour>,
}

impl From<String> for Palette {
    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)
    }
}

#[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);
}