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
extern crate icns;
use crate::{Icon, Entry, SourceImage, Error, STD_CAPACITY};
use std::{result, io::{self, Write}, fmt::{self, Debug, Formatter}};
use image::{DynamicImage, GenericImageView};
pub struct Icns {
icon_family: icns::IconFamily,
entries: Vec<u32>
}
impl Icon<Entry> for Icns {
fn new() -> Self {
Icns {
icon_family: icns::IconFamily::new(),
entries: Vec::with_capacity(STD_CAPACITY)
}
}
fn add_entry<F: FnMut(&SourceImage, u32) -> DynamicImage>(
&mut self,
mut filter: F,
source: &SourceImage,
entry: Entry
) -> Result<(), Error<Entry>> {
let icon = filter(source, entry.0);
let data = icon.to_rgba().into_vec();
if self.entries.contains(&entry.0) {
return Err(Error::AlreadyIncluded(entry));
}
let image = icns::Image::from_data(icns::PixelFormat::RGBA, entry.0, entry.0, data)
.map_err(|_| Error::InvalidDimensions(entry.0, icon.dimensions()))?;
self.icon_family.add_icon(&image)
.map_err(|_| Error::InvalidSize(entry.0))
}
fn write<W: Write>(&mut self, w: &mut W) -> io::Result<()> {
self.icon_family.write(w)
}
}
impl Clone for Icns {
fn clone(&self) -> Self {
let mut icon_family = icns::IconFamily {
elements: Vec::with_capacity(self.icon_family.elements.len())
};
for element in &self.icon_family.elements {
let clone = icns::IconElement::new(element.ostype, element.data.clone());
icon_family.elements.push(clone);
}
Icns {
icon_family,
entries: self.entries.clone()
}
}
}
macro_rules! element {
($elm:expr) => {
format!("IconElement {{ ostype: {:?}, data: {:?} }}", $elm.ostype, $elm.data )
};
}
impl Debug for Icns {
fn fmt(&self, f: &mut Formatter) -> result::Result<(), fmt::Error> {
let entries_strs: Vec<String> = self.icon_family.elements.iter()
.map(|element| element!(element)).collect();
let icon_dir = format!(
"icns::IconFamily {{ elements: [{}] }}",
entries_strs.join(", ")
);
write!(f, "iconwriter::Icns {{ icon_family: {} }} ", icon_dir)
}
}