debcontrol_struct_with_oma_decontrol/
lib.rs1use debcontrol::Paragraph;
32
33pub trait DebControl {
34 fn from_paragraph(p: &Paragraph) -> Result<Self, &'static str>
35 where
36 Self: Sized;
37
38 fn to_paragraph(&self) -> Paragraph;
39}
40
41#[cfg(feature = "derive")]
43#[doc(hidden)]
44pub use debcontrol_struct_derive::DebControl;
45
46#[cfg(test)]
47mod manual {
48 use crate::*;
49 use debcontrol::{Field, Paragraph};
50
51 macro_rules! mandatory {
52 ( $x:expr ) => {{
53 $x.ok_or(concat!(
54 "Could not find the mandatory \"",
55 stringify!($x),
56 "\" field in paragraph"
57 ))
58 }};
59 }
60
61 struct StandaloneLicense {
62 license: String,
63 comment: Option<String>,
64 }
65
66 impl DebControl for StandaloneLicense {
67 fn from_paragraph(p: &Paragraph) -> Result<Self, &'static str> {
68 let mut license = None;
69 let mut comment = None;
70
71 for field in &p.fields {
72 match field.name {
73 "License" => {
74 license = Some(field.value.clone());
75 }
76 "Comment" => {
77 comment = Some(field.value.clone());
78 }
79 _ => {}
80 }
81 }
82
83 let license = mandatory!(license)?;
84 Ok(StandaloneLicense { license, comment })
85 }
86
87 fn to_paragraph(&self) -> Paragraph {
88 let mut p = Paragraph {
89 fields: vec![
90 Field {
91 name: "License",
92 value: self.license.clone(),
93 }
94 ]
95 };
96
97 if let Some(comment) = &self.comment {
98 p.fields.push(Field {name: "Comment", value: comment.to_string()});
99 }
100
101 p
102 }
103 }
104
105 #[test]
106 fn test_parse_standalone_license() {
107 let input = Paragraph {
108 fields: vec![Field {
109 name: "License",
110 value: "Expat".into(),
111 }],
112 };
113
114 let license = StandaloneLicense::from_paragraph(&input).unwrap();
115
116 assert_eq!("Expat", license.license);
117 assert_eq!(None, license.comment);
118 }
119
120 #[test]
121 fn test_parse_standalone_license_extended() {
122 let input = Paragraph {
123 fields: vec![
124 Field {
125 name: "License",
126 value: "Expat".into(),
127 },
128 Field {
129 name: "Comment",
130 value: "Curious license to use...".into(),
131 },
132 ],
133 };
134
135 let license = StandaloneLicense::from_paragraph(&input).unwrap();
136
137 assert_eq!("Expat", license.license);
138 assert_eq!("Curious license to use...", license.comment.unwrap());
139 }
140
141 #[test]
142 fn test_parse_standalone_license_bogus() {
143 let input = Paragraph {
144 fields: vec![Field {
145 name: "Lic",
146 value: "Expat".into(),
147 }],
148 };
149
150 assert!(StandaloneLicense::from_paragraph(&input).is_err());
151 }
152
153 #[test]
154 fn test_to_paragraph() {
155 let expected = Paragraph {
156 fields: vec![Field {
157 name: "License",
158 value: "Expat".into(),
159 }],
160 };
161
162 let value = StandaloneLicense {
163 license: "Expat".into(),
164 comment: None,
165 };
166
167 assert_eq!(expected, value.to_paragraph());
168 }
169
170 #[test]
171 fn test_to_paragraph_extended() {
172 let expected = Paragraph {
173 fields: vec![
174 Field {
175 name: "License",
176 value: "Expat".into(),
177 },
178 Field {
179 name: "Comment",
180 value: "Curious license to use...".into(),
181 }],
182 };
183
184 let value = StandaloneLicense {
185 license: "Expat".into(),
186 comment: Some("Curious license to use...".into()),
187 };
188
189 assert_eq!(expected, value.to_paragraph());
190 }
191}
192
193#[cfg(feature = "derive")]
194#[cfg(test)]
195mod derive {
196 use crate::*;
197 use debcontrol::{Field, Paragraph};
198 use debcontrol_struct_derive::DebControl;
199
200 #[derive(DebControl)]
201 struct DerivedStruct {
202 first: String,
203 multiple_words: String,
204 optional: Option<String>,
205 }
206
207 #[test]
208 fn test_parse_derived() {
209 let input = Paragraph {
210 fields: vec![
211 Field {
212 name: "First",
213 value: "Hello".into(),
214 },
215 Field {
216 name: "Multiple-Words",
217 value: "World".into(),
218 },
219 ],
220 };
221
222 let derived = DerivedStruct::from_paragraph(&input).unwrap();
223
224 assert_eq!("Hello", derived.first);
225 assert_eq!("World", derived.multiple_words);
226 assert_eq!(None, derived.optional);
227 }
228
229 #[test]
230 fn test_parse_derived_extended() {
231 let input = Paragraph {
232 fields: vec![
233 Field {
234 name: "First",
235 value: "Hello".into(),
236 },
237 Field {
238 name: "Multiple-Words",
239 value: "World".into(),
240 },
241 Field {
242 name: "Optional",
243 value: "!".into(),
244 },
245 ],
246 };
247
248 let derived = DerivedStruct::from_paragraph(&input).unwrap();
249
250 assert_eq!("Hello", derived.first);
251 assert_eq!("World", derived.multiple_words);
252 assert_eq!(Some("!".into()), derived.optional);
253 }
254
255 #[test]
256 fn test_parse_derived_bogus() {
257 let input = Paragraph {
258 fields: vec![Field {
259 name: "First",
260 value: "Hello".into(),
261 }],
262 };
263
264 assert!(DerivedStruct::from_paragraph(&input).is_err());
265 }
266
267 #[test]
268 fn test_to_paragraph() {
269 let expected = Paragraph {
270 fields: vec![
271 Field {
272 name: "First",
273 value: "Hello".into(),
274 },
275 Field {
276 name: "Multiple-Words",
277 value: "World".into(),
278 },
279 ],
280 };
281
282 let value = DerivedStruct {
283 first: "Hello".into(),
284 multiple_words: "World".into(),
285 optional: None,
286 };
287
288 assert_eq!(expected, value.to_paragraph());
289 }
290
291 #[test]
292 fn test_to_paragraph_extended() {
293 let expected = Paragraph {
294 fields: vec![
295 Field {
296 name: "First",
297 value: "Hello".into(),
298 },
299 Field {
300 name: "Multiple-Words",
301 value: "World".into(),
302 },
303 Field {
304 name: "Optional",
305 value: "!".into(),
306 },
307 ],
308 };
309
310 let value = DerivedStruct {
311 first: "Hello".into(),
312 multiple_words: "World".into(),
313 optional: Some("!".into()),
314 };
315
316 assert_eq!(expected, value.to_paragraph());
317 }
318}