1#[cfg(feature = "zbus-backend")]
4use crate::proxy::RawMedia;
5
6#[derive(Debug, Clone)]
8pub struct MarginInfo {
9 pub left: i32,
11 pub right: i32,
13 pub top: i32,
15 pub bottom: i32,
17}
18
19#[derive(Debug, Clone)]
21pub struct MediaInfo {
22 pub name: String,
24 pub width: i32,
26 pub length: i32,
28 pub margins: Vec<MarginInfo>,
30}
31
32#[derive(Debug, Clone, Default)]
34pub struct MediaCollection {
35 pub media: Vec<MediaInfo>,
37}
38
39impl MediaCollection {
40 #[cfg(feature = "zbus-backend")]
42 pub fn from_dbus(raw: Vec<RawMedia>) -> Self {
43 let media = raw
44 .into_iter()
45 .map(|r| MediaInfo {
46 name: r.name,
47 width: r.width,
48 length: r.length,
49 margins: r
50 .margins
51 .into_iter()
52 .map(|m| MarginInfo {
53 left: m.left,
54 right: m.right,
55 top: m.top,
56 bottom: m.bottom,
57 })
58 .collect(),
59 })
60 .collect();
61 Self { media }
62 }
63
64 pub fn len(&self) -> usize {
66 self.media.len()
67 }
68
69 pub fn is_empty(&self) -> bool {
71 self.media.is_empty()
72 }
73
74 pub fn get(&self, name: &str) -> Option<&MediaInfo> {
76 self.media.iter().find(|m| m.name == name)
77 }
78
79 pub fn iter(&self) -> impl Iterator<Item = &MediaInfo> {
81 self.media.iter()
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88
89 fn sample_media() -> MediaCollection {
90 MediaCollection {
91 media: vec![
92 MediaInfo {
93 name: "iso_a4_210x297mm".to_string(),
94 width: 21000,
95 length: 29700,
96 margins: vec![MarginInfo {
97 left: 500,
98 right: 500,
99 top: 500,
100 bottom: 500,
101 }],
102 },
103 MediaInfo {
104 name: "na_letter_8.5x11in".to_string(),
105 width: 21590,
106 length: 27940,
107 margins: vec![],
108 },
109 ],
110 }
111 }
112
113 #[test]
114 fn empty_collection() {
115 let col = MediaCollection::default();
116 assert!(col.is_empty());
117 assert_eq!(col.len(), 0);
118 assert!(col.get("iso_a4_210x297mm").is_none());
119 }
120
121 #[test]
122 fn len_and_is_empty() {
123 let col = sample_media();
124 assert!(!col.is_empty());
125 assert_eq!(col.len(), 2);
126 }
127
128 #[test]
129 fn get_finds_by_name() {
130 let col = sample_media();
131 let a4 = col.get("iso_a4_210x297mm");
132 assert!(a4.is_some());
133 let a4 = a4.unwrap();
134 assert_eq!(a4.width, 21000);
135 assert_eq!(a4.length, 29700);
136 assert_eq!(a4.margins.len(), 1);
137 assert_eq!(a4.margins[0].left, 500);
138 }
139
140 #[test]
141 fn get_returns_none_for_missing() {
142 let col = sample_media();
143 assert!(col.get("nonexistent_paper").is_none());
144 }
145
146 #[test]
147 fn iter_yields_all_entries() {
148 let col = sample_media();
149 let names: Vec<&str> = col.iter().map(|m| m.name.as_str()).collect();
150 assert!(names.contains(&"iso_a4_210x297mm"));
151 assert!(names.contains(&"na_letter_8.5x11in"));
152 }
153
154 #[test]
155 fn media_without_margins() {
156 let col = sample_media();
157 let letter = col.get("na_letter_8.5x11in").unwrap();
158 assert!(letter.margins.is_empty());
159 }
160
161 #[cfg(feature = "zbus-backend")]
162 #[test]
163 fn from_dbus_empty_vec() {
164 let col = MediaCollection::from_dbus(vec![]);
165 assert!(col.is_empty());
166 }
167
168 #[cfg(feature = "zbus-backend")]
169 #[test]
170 fn from_dbus_converts_correctly() {
171 use crate::proxy::{RawMargin, RawMedia};
172
173 let raw = vec![RawMedia {
174 name: "iso_a4_210x297mm".to_string(),
175 width: 21000,
176 length: 29700,
177 num_margins: 1,
178 margins: vec![RawMargin {
179 left: 500,
180 right: 500,
181 top: 300,
182 bottom: 300,
183 }],
184 }];
185
186 let col = MediaCollection::from_dbus(raw);
187 assert_eq!(col.len(), 1);
188 let a4 = &col.media[0];
189 assert_eq!(a4.name, "iso_a4_210x297mm");
190 assert_eq!(a4.width, 21000);
191 assert_eq!(a4.margins.len(), 1);
192 assert_eq!(a4.margins[0].top, 300);
193 }
194}