2021-05-16 14:00:13 +01:00
|
|
|
use std::fs::read_to_string;
|
|
|
|
|
use std::path::PathBuf;
|
2021-05-15 16:59:51 +01:00
|
|
|
use serde_derive::{Serialize, Deserialize};
|
|
|
|
|
use crate::colour::Colour;
|
|
|
|
|
|
2021-05-16 14:00:13 +01:00
|
|
|
/// todo enumerate original format
|
2021-05-15 16:59:51 +01:00
|
|
|
#[derive(Debug, Eq, PartialEq, Serialize, Deserialize)]
|
|
|
|
|
pub struct Palette {
|
|
|
|
|
pub name: String,
|
|
|
|
|
pub colours: Vec<Colour>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Palette {
|
|
|
|
|
pub fn from(name: &str, toml: &str) -> Self {
|
|
|
|
|
let intermediate: IntermediatePalette = toml::from_str(toml).unwrap();
|
|
|
|
|
|
|
|
|
|
println!("palette name: {}", name);
|
|
|
|
|
|
|
|
|
|
for colour in &intermediate.colours {
|
|
|
|
|
println!("palette colour: {}{}{}", colour[0], colour[1], colour[2]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Palette {
|
|
|
|
|
name: name.to_string(),
|
|
|
|
|
colours: intermediate.colours.iter().map(|vec| {
|
|
|
|
|
Colour::from(vec.clone())
|
|
|
|
|
}).collect(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-16 14:00:13 +01:00
|
|
|
/// JASC .pal format (Paint Shop Pro)
|
|
|
|
|
pub fn from_jasc(path: PathBuf) -> Self {
|
|
|
|
|
let name = path.file_stem().unwrap().to_str().unwrap().into();
|
|
|
|
|
let mut colours = Vec::new();
|
|
|
|
|
|
|
|
|
|
for (index, line) in read_to_string(&path).unwrap().lines().enumerate() {
|
|
|
|
|
// ignore the first 3 lines
|
|
|
|
|
if index > 2 {
|
|
|
|
|
let mut values: Vec<u8> = Vec::new();
|
|
|
|
|
|
|
|
|
|
for value in line.split_whitespace() {
|
|
|
|
|
values.push(value.parse().unwrap());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
colours.push(Colour::from(values));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Palette { name, colours }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn to_jasc(&self) -> String {
|
|
|
|
|
let colours: Vec<String> = self.colours.iter().map(|colour|
|
|
|
|
|
format!("{} {} {}", colour.red, colour.green, colour.blue)
|
|
|
|
|
).collect();
|
|
|
|
|
|
|
|
|
|
format!("JASC-PAL\r\n0100\r\n{}\r\n{}\r\n", self.colours.len(), colours.join("\r\n"))
|
2021-05-15 16:59:51 +01:00
|
|
|
}
|
2021-05-16 15:53:26 +01:00
|
|
|
|
|
|
|
|
/// GIMP .gpl format
|
|
|
|
|
pub fn from_gpl(path: PathBuf) -> Self {
|
|
|
|
|
let name = path.file_stem().unwrap().to_str().unwrap().into();
|
|
|
|
|
|
|
|
|
|
let mut colours = Vec::new();
|
|
|
|
|
|
|
|
|
|
for (index, line) in read_to_string(&path).unwrap().lines().enumerate() {
|
|
|
|
|
// ignore header and comments
|
|
|
|
|
if index > 0 && !line.starts_with("#") {
|
|
|
|
|
let parts = line.split_whitespace();
|
|
|
|
|
colours.push(Colour::from(parts.last().unwrap()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Self { name, colours }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// GIMP .gpl format
|
|
|
|
|
pub fn to_gpl(&self) -> String {
|
|
|
|
|
let colours: Vec<String> = self.colours.iter().map(|colour| {
|
|
|
|
|
format!(
|
|
|
|
|
"{}\t{}\t{}\t{}",
|
|
|
|
|
colour.red,
|
|
|
|
|
colour.green,
|
|
|
|
|
colour.blue,
|
|
|
|
|
colour.to_string().replace('#', "")
|
|
|
|
|
)
|
|
|
|
|
}).collect();
|
|
|
|
|
|
|
|
|
|
// todo re-insert original comments
|
|
|
|
|
format!("GIMP Palette\r\n{}\r\n", colours.join("\r\n"))
|
|
|
|
|
}
|
2021-05-15 16:59:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// for toml purposes
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
|
pub struct IntermediatePalette {
|
|
|
|
|
pub colours: Vec<Vec<u8>>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// for toml purposes
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
|
struct IntermediatePalettes {
|
|
|
|
|
/// singular so each palette section is named "palette" instead of "palettes" in toml
|
|
|
|
|
palette: Vec<IntermediatePalette>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl IntermediatePalettes {
|
|
|
|
|
pub fn from_dir() -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
palette: vec![]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod test {
|
2021-05-16 14:00:13 +01:00
|
|
|
use std::path::PathBuf;
|
|
|
|
|
use crate::{Colour, Palette};
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn palette_from_jasc() {
|
|
|
|
|
let path = PathBuf::from("src/test-resources/basic/palettes/soup11.pal");
|
|
|
|
|
let output = Palette::from_jasc(path);
|
|
|
|
|
|
|
|
|
|
let expected = Palette {
|
|
|
|
|
name: "soup11".into(),
|
|
|
|
|
colours: vec![
|
|
|
|
|
Colour { red: 79, green: 30, blue: 69 },
|
|
|
|
|
Colour { red: 150, green: 48, blue: 87 },
|
|
|
|
|
Colour { red: 215, green: 68, blue: 89 },
|
|
|
|
|
Colour { red: 235, green: 112, blue: 96 },
|
|
|
|
|
Colour { red: 255, green: 179, blue: 131 },
|
|
|
|
|
Colour { red: 255, green: 255, blue: 255 },
|
|
|
|
|
Colour { red: 127, green: 227, blue: 187 },
|
|
|
|
|
Colour { red: 92, green: 187, blue: 196 },
|
|
|
|
|
Colour { red: 69, green: 126, blue: 163 },
|
|
|
|
|
Colour { red: 56, green: 66, blue: 118 },
|
|
|
|
|
Colour { red: 50, green: 36, blue: 81 }
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
assert_eq!(output, expected);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn palette_to_jasc() {
|
2021-05-16 15:53:26 +01:00
|
|
|
let output = crate::mock::palette::soup11().to_jasc();
|
2021-05-16 14:00:13 +01:00
|
|
|
let expected = include_str!("test-resources/basic/palettes/soup11.pal");
|
|
|
|
|
assert_eq!(output, expected);
|
|
|
|
|
}
|
2021-05-15 16:59:51 +01:00
|
|
|
|
2021-05-16 15:53:26 +01:00
|
|
|
#[test]
|
|
|
|
|
fn palette_from_gpl() {
|
|
|
|
|
let path = PathBuf::from("src/test-resources/basic/palettes/soup11.gpl");
|
|
|
|
|
let output = Palette::from_gpl(path);
|
|
|
|
|
let expected = crate::mock::palette::soup11();
|
|
|
|
|
|
|
|
|
|
assert_eq!(output, expected);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn palette_to_gpl() {
|
|
|
|
|
let output = crate::mock::palette::soup11().to_gpl();
|
|
|
|
|
let expected = include_str!("test-resources/basic/palettes/soup11.gpl");
|
|
|
|
|
|
|
|
|
|
assert_eq!(output, expected);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-15 16:59:51 +01:00
|
|
|
#[test]
|
2021-05-16 14:00:13 +01:00
|
|
|
fn palette_from_toml() {
|
2021-05-15 16:59:51 +01:00
|
|
|
let output = Palette::from(
|
|
|
|
|
"blueprint",
|
|
|
|
|
include_str!("test-resources/basic/palettes/blueprint.toml")
|
|
|
|
|
);
|
|
|
|
|
let expected = crate::mock::palette::default();
|
|
|
|
|
assert_eq!(output, expected);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2021-05-16 14:00:13 +01:00
|
|
|
fn palette_to_toml() {
|
2021-05-15 16:59:51 +01:00
|
|
|
let intermediate = crate::mock::palette::intermediate();
|
|
|
|
|
let output = toml::to_string(&intermediate).unwrap();
|
|
|
|
|
let expected = include_str!("test-resources/basic/palettes/blueprint.toml");
|
|
|
|
|
assert_eq!(&output, expected);
|
|
|
|
|
}
|
|
|
|
|
}
|