imgdata/
io.rs

1use crate::color;
2use image::{Rgba, RgbaImage};
3use ron;
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6use std::fs::File;
7use std::io::{self, Write};
8
9#[derive(Clone, Debug, Default, Serialize, Deserialize)]
10pub struct ColorEntry {
11    pub name: String,
12    // Color is a hexidecimal 3-component, RGB color with no alpha
13    pub color: String,
14}
15
16pub fn open(path: &str) -> RgbaImage {
17    return image::open(path).unwrap().to_rgba();
18}
19
20pub fn read(path: &str) -> ColorFile {
21    let f = File::open(path).expect("Failed opening file");
22    let color_file: ColorFile = match ron::de::from_reader(f) {
23        Ok(x) => x,
24        Err(e) => {
25            panic!("Failed to load color-file: {}", e);
26        }
27    };
28    return color_file;
29}
30
31#[derive(Clone, Debug, Default, Serialize, Deserialize)]
32pub struct ColorFile {
33    pub entries: Vec<ColorEntry>,
34}
35
36impl ColorFile {
37    pub fn new(colors: Vec<String>) -> ColorFile {
38        ColorFile {
39            entries: colors
40                .iter()
41                .map(|x| ColorEntry {
42                    name: String::from(""),
43                    color: x.clone(),
44                })
45                .collect(),
46        }
47    }
48    pub fn create_lookup(&self) -> HashMap<Rgba<u8>, String> {
49        let mut lookup = HashMap::new();
50        for color_entry in self.entries.iter() {
51            let c = color::from_hex(color_entry.color.clone());
52            lookup.insert(c, color_entry.name.clone());
53        }
54        return lookup;
55    }
56
57    pub fn write(&self, path: &str) -> io::Result<()> {
58        let serialized = ron::ser::to_string(self).expect("Serialization failed");
59        match File::create(path) {
60            Ok(mut file) => {
61                file.write_all(serialized.as_bytes())?;
62                Ok(())
63            }
64            _ => panic!("Could not write color file!"),
65        }
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72
73    #[test]
74    fn test_open() {
75        let img = open("src/test-image.png");
76        assert_eq!(img.dimensions(), (4, 4));
77    }
78
79    #[test]
80    fn test_read() {
81        let color_file = read("src/test-color-file.ron");
82
83        assert_eq!(color_file.entries[0].name, "thing1");
84        assert_eq!(color_file.entries[0].color, "#123abc");
85        assert_eq!(color_file.entries[1].name, "thing2");
86        assert_eq!(color_file.entries[1].color, "#abc123");
87    }
88
89    #[test]
90    fn test_new_color_file() {
91        let color_file = ColorFile::new(vec![String::from("#abc123"), String::from("#123abc")]);
92        assert_eq!(color_file.entries[0].name, "");
93        assert_eq!(color_file.entries[0].color, "#abc123");
94        assert_eq!(color_file.entries[1].name, "");
95        assert_eq!(color_file.entries[1].color, "#123abc");
96    }
97
98    #[test]
99    fn test_create_lookup() {
100        let color_file = read("src/test-color-file.ron");
101        let lu = color_file.create_lookup();
102        let c1 = color::from_hex(String::from("#123abc").clone());
103        let c2 = color::from_hex(String::from("#abc123").clone());
104
105        match lu.get(&c1) {
106            Some(name) => assert_eq!(name.clone(), "thing1"),
107            _ => panic!("WAT"),
108        }
109
110        match lu.get(&c2) {
111            Some(name) => assert_eq!(name.clone(), "thing2"),
112            _ => panic!("WUT"),
113        }
114    }
115}