1use crate::fields::{MultiArch, Priority};
36use crate::lossless::relations::Relations;
37
38fn format_field(name: &str, value: &str) -> String {
39 match name {
40 "Uploaders" => value
41 .split(',')
42 .map(|s| s.trim().to_string())
43 .collect::<Vec<_>>()
44 .join(",\n"),
45 "Build-Depends"
46 | "Build-Depends-Indep"
47 | "Build-Depends-Arch"
48 | "Build-Conflicts"
49 | "Build-Conflicts-Indep"
50 | "Build-Conflics-Arch"
51 | "Depends"
52 | "Recommends"
53 | "Suggests"
54 | "Enhances"
55 | "Pre-Depends"
56 | "Breaks" => {
57 let relations: Relations = value.parse().unwrap();
58 let relations = relations.wrap_and_sort();
59 relations.to_string()
60 }
61 _ => value.to_string(),
62 }
63}
64
65pub struct Control(deb822_lossless::Deb822);
67
68impl Control {
69 pub fn new() -> Self {
71 Control(deb822_lossless::Deb822::new())
72 }
73
74 pub fn as_mut_deb822(&mut self) -> &mut deb822_lossless::Deb822 {
76 &mut self.0
77 }
78
79 pub fn as_deb822(&self) -> &deb822_lossless::Deb822 {
81 &self.0
82 }
83
84 pub fn source(&self) -> Option<Source> {
86 self.0
87 .paragraphs()
88 .find(|p| p.get("Source").is_some())
89 .map(Source)
90 }
91
92 pub fn binaries(&self) -> impl Iterator<Item = Binary> {
94 self.0
95 .paragraphs()
96 .filter(|p| p.get("Package").is_some())
97 .map(Binary)
98 }
99
100 pub fn add_source(&mut self, name: &str) -> Source {
116 let mut p = self.0.add_paragraph();
117 p.set("Source", name);
118 self.source().unwrap()
119 }
120
121 pub fn add_binary(&mut self, name: &str) -> Binary {
137 let mut p = self.0.add_paragraph();
138 p.set("Package", name);
139 Binary(p)
140 }
141
142 pub fn from_file<P: AsRef<std::path::Path>>(path: P) -> Result<Self, deb822_lossless::Error> {
144 Ok(Control(deb822_lossless::Deb822::from_file(path)?))
145 }
146
147 pub fn from_file_relaxed<P: AsRef<std::path::Path>>(
149 path: P,
150 ) -> Result<(Self, Vec<String>), std::io::Error> {
151 let (control, errors) = deb822_lossless::Deb822::from_file_relaxed(path)?;
152 Ok((Control(control), errors))
153 }
154
155 pub fn read<R: std::io::Read>(mut r: R) -> Result<Self, deb822_lossless::Error> {
157 Ok(Control(deb822_lossless::Deb822::read(&mut r)?))
158 }
159
160 pub fn read_relaxed<R: std::io::Read>(
162 mut r: R,
163 ) -> Result<(Self, Vec<String>), deb822_lossless::Error> {
164 let (control, errors) = deb822_lossless::Deb822::read_relaxed(&mut r)?;
165 Ok((Self(control), errors))
166 }
167
168 pub fn wrap_and_sort(
175 &mut self,
176 indentation: deb822_lossless::Indentation,
177 immediate_empty_line: bool,
178 max_line_length_one_liner: Option<usize>,
179 ) {
180 let sort_paragraphs = |a: &deb822_lossless::Paragraph,
181 b: &deb822_lossless::Paragraph|
182 -> std::cmp::Ordering {
183 let a_is_source = a.get("Source").is_some();
185 let b_is_source = b.get("Source").is_some();
186
187 if a_is_source && !b_is_source {
188 return std::cmp::Ordering::Less;
189 } else if !a_is_source && b_is_source {
190 return std::cmp::Ordering::Greater;
191 } else if a_is_source && b_is_source {
192 return a.get("Source").cmp(&b.get("Source"));
193 }
194
195 a.get("Package").cmp(&b.get("Package"))
196 };
197
198 let wrap_paragraph = |p: &deb822_lossless::Paragraph| -> deb822_lossless::Paragraph {
199 p.wrap_and_sort(
202 indentation,
203 immediate_empty_line,
204 max_line_length_one_liner,
205 None,
206 Some(&format_field),
207 )
208 };
209
210 self.0 = self
211 .0
212 .wrap_and_sort(Some(&sort_paragraphs), Some(&wrap_paragraph));
213 }
214}
215
216impl From<Control> for deb822_lossless::Deb822 {
217 fn from(c: Control) -> Self {
218 c.0
219 }
220}
221
222impl From<deb822_lossless::Deb822> for Control {
223 fn from(d: deb822_lossless::Deb822) -> Self {
224 Control(d)
225 }
226}
227
228impl Default for Control {
229 fn default() -> Self {
230 Self::new()
231 }
232}
233
234impl std::str::FromStr for Control {
235 type Err = deb822_lossless::ParseError;
236
237 fn from_str(s: &str) -> Result<Self, Self::Err> {
238 Ok(Control(s.parse()?))
239 }
240}
241
242pub struct Source(deb822_lossless::Paragraph);
244
245impl From<Source> for deb822_lossless::Paragraph {
246 fn from(s: Source) -> Self {
247 s.0
248 }
249}
250
251impl From<deb822_lossless::Paragraph> for Source {
252 fn from(p: deb822_lossless::Paragraph) -> Self {
253 Source(p)
254 }
255}
256
257impl std::fmt::Display for Source {
258 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
259 self.0.fmt(f)
260 }
261}
262
263impl Source {
264 pub fn name(&self) -> Option<String> {
266 self.0.get("Source")
267 }
268
269 pub fn wrap_and_sort(
271 &mut self,
272 indentation: deb822_lossless::Indentation,
273 immediate_empty_line: bool,
274 max_line_length_one_liner: Option<usize>,
275 ) {
276 self.0 = self.0.wrap_and_sort(
277 indentation,
278 immediate_empty_line,
279 max_line_length_one_liner,
280 None,
281 Some(&format_field),
282 );
283 }
284
285 pub fn as_mut_deb822(&mut self) -> &mut deb822_lossless::Paragraph {
287 &mut self.0
288 }
289
290 pub fn as_deb822(&self) -> &deb822_lossless::Paragraph {
292 &self.0
293 }
294
295 pub fn set_name(&mut self, name: &str) {
297 self.0.set("Source", name);
298 }
299
300 pub fn section(&self) -> Option<String> {
302 self.0.get("Section")
303 }
304
305 pub fn set_section(&mut self, section: Option<&str>) {
307 if let Some(section) = section {
308 self.0.set("Section", section);
309 } else {
310 self.0.remove("Section");
311 }
312 }
313
314 pub fn priority(&self) -> Option<Priority> {
316 self.0.get("Priority").and_then(|v| v.parse().ok())
317 }
318
319 pub fn set_priority(&mut self, priority: Option<Priority>) {
321 if let Some(priority) = priority {
322 self.0.set("Priority", priority.to_string().as_str());
323 } else {
324 self.0.remove("Priority");
325 }
326 }
327
328 pub fn maintainer(&self) -> Option<String> {
330 self.0.get("Maintainer")
331 }
332
333 pub fn set_maintainer(&mut self, maintainer: &str) {
335 self.0.set("Maintainer", maintainer);
336 }
337
338 pub fn build_depends(&self) -> Option<Relations> {
340 self.0.get("Build-Depends").map(|s| s.parse().unwrap())
341 }
342
343 pub fn set_build_depends(&mut self, relations: &Relations) {
345 self.0.set("Build-Depends", relations.to_string().as_str());
346 }
347
348 pub fn build_depends_indep(&self) -> Option<Relations> {
350 self.0
351 .get("Build-Depends-Indep")
352 .map(|s| s.parse().unwrap())
353 }
354
355 pub fn build_depends_arch(&self) -> Option<Relations> {
357 self.0.get("Build-Depends-Arch").map(|s| s.parse().unwrap())
358 }
359
360 pub fn build_conflicts(&self) -> Option<Relations> {
362 self.0.get("Build-Conflicts").map(|s| s.parse().unwrap())
363 }
364
365 pub fn build_conflicts_indep(&self) -> Option<Relations> {
367 self.0
368 .get("Build-Conflicts-Indep")
369 .map(|s| s.parse().unwrap())
370 }
371
372 pub fn build_conflicts_arch(&self) -> Option<Relations> {
374 self.0
375 .get("Build-Conflicts-Arch")
376 .map(|s| s.parse().unwrap())
377 }
378
379 pub fn standards_version(&self) -> Option<String> {
381 self.0.get("Standards-Version")
382 }
383
384 pub fn set_standards_version(&mut self, version: &str) {
386 self.0.set("Standards-Version", version);
387 }
388
389 pub fn homepage(&self) -> Option<url::Url> {
391 self.0.get("Homepage").and_then(|s| s.parse().ok())
392 }
393
394 pub fn set_homepage(&mut self, homepage: &url::Url) {
396 self.0.set("Homepage", homepage.to_string().as_str());
397 }
398
399 pub fn vcs_git(&self) -> Option<String> {
401 self.0.get("Vcs-Git")
402 }
403
404 pub fn set_vcs_git(&mut self, url: &str) {
406 self.0.set("Vcs-Git", url);
407 }
408
409 pub fn vcs_svn(&self) -> Option<String> {
411 self.0.get("Vcs-Svn").map(|s| s.to_string())
412 }
413
414 pub fn set_vcs_svn(&mut self, url: &str) {
416 self.0.set("Vcs-Svn", url);
417 }
418
419 pub fn vcs_bzr(&self) -> Option<String> {
421 self.0.get("Vcs-Bzr").map(|s| s.to_string())
422 }
423
424 pub fn set_vcs_bzr(&mut self, url: &str) {
426 self.0.set("Vcs-Bzr", url);
427 }
428
429 pub fn vcs_arch(&self) -> Option<String> {
431 self.0.get("Vcs-Arch").map(|s| s.to_string())
432 }
433
434 pub fn set_vcs_arch(&mut self, url: &str) {
436 self.0.set("Vcs-Arch", url);
437 }
438
439 pub fn vcs_svk(&self) -> Option<String> {
441 self.0.get("Vcs-Svk").map(|s| s.to_string())
442 }
443
444 pub fn set_vcs_svk(&mut self, url: &str) {
446 self.0.set("Vcs-Svk", url);
447 }
448
449 pub fn vcs_darcs(&self) -> Option<String> {
451 self.0.get("Vcs-Darcs").map(|s| s.to_string())
452 }
453
454 pub fn set_vcs_darcs(&mut self, url: &str) {
456 self.0.set("Vcs-Darcs", url);
457 }
458
459 pub fn vcs_mtn(&self) -> Option<String> {
461 self.0.get("Vcs-Mtn").map(|s| s.to_string())
462 }
463
464 pub fn set_vcs_mtn(&mut self, url: &str) {
466 self.0.set("Vcs-Mtn", url);
467 }
468
469 pub fn vcs_cvs(&self) -> Option<String> {
471 self.0.get("Vcs-Cvs").map(|s| s.to_string())
472 }
473
474 pub fn set_vcs_cvs(&mut self, url: &str) {
476 self.0.set("Vcs-Cvs", url);
477 }
478
479 pub fn vcs_hg(&self) -> Option<String> {
481 self.0.get("Vcs-Hg").map(|s| s.to_string())
482 }
483
484 pub fn set_vcs_hg(&mut self, url: &str) {
486 self.0.set("Vcs-Hg", url);
487 }
488
489 pub fn vcs_browser(&self) -> Option<String> {
491 self.0.get("Vcs-Browser")
492 }
493
494 pub fn vcs(&self) -> Option<crate::vcs::Vcs> {
496 for (name, value) in self.0.items() {
497 if name.starts_with("Vcs-") && name != "Vcs-Browser" {
498 return crate::vcs::Vcs::from_field(&name, &value).ok();
499 }
500 }
501 None
502 }
503
504 pub fn set_vcs_browser(&mut self, url: Option<&str>) {
506 if let Some(url) = url {
507 self.0.set("Vcs-Browser", url);
508 } else {
509 self.0.remove("Vcs-Browser");
510 }
511 }
512
513 pub fn uploaders(&self) -> Option<Vec<String>> {
515 self.0
516 .get("Uploaders")
517 .map(|s| s.split(',').map(|s| s.trim().to_owned()).collect())
518 }
519
520 pub fn set_uploaders(&mut self, uploaders: &[&str]) {
522 self.0.set(
523 "Uploaders",
524 uploaders
525 .iter()
526 .map(|s| s.to_string())
527 .collect::<Vec<_>>()
528 .join(", ")
529 .as_str(),
530 );
531 }
532
533 pub fn architecture(&self) -> Option<String> {
535 self.0.get("Architecture")
536 }
537
538 pub fn set_architecture(&mut self, arch: Option<&str>) {
540 if let Some(arch) = arch {
541 self.0.set("Architecture", arch);
542 } else {
543 self.0.remove("Architecture");
544 }
545 }
546
547 pub fn rules_requires_root(&self) -> Option<bool> {
549 self.0
550 .get("Rules-Requires-Root")
551 .map(|s| match s.to_lowercase().as_str() {
552 "yes" => true,
553 "no" => false,
554 _ => panic!("invalid Rules-Requires-Root value"),
555 })
556 }
557
558 pub fn set_rules_requires_root(&mut self, requires_root: bool) {
560 self.0.set(
561 "Rules-Requires-Root",
562 if requires_root { "yes" } else { "no" },
563 );
564 }
565
566 pub fn testsuite(&self) -> Option<String> {
568 self.0.get("Testsuite")
569 }
570
571 pub fn set_testsuite(&mut self, testsuite: &str) {
573 self.0.set("Testsuite", testsuite);
574 }
575}
576
577#[cfg(feature = "python-debian")]
578impl pyo3::ToPyObject for Source {
579 fn to_object(&self, py: pyo3::Python) -> pyo3::PyObject {
580 self.0.to_object(py)
581 }
582}
583
584#[cfg(feature = "python-debian")]
585impl pyo3::FromPyObject<'_> for Source {
586 fn extract_bound(ob: &pyo3::Bound<pyo3::PyAny>) -> pyo3::PyResult<Self> {
587 use pyo3::prelude::*;
588 Ok(Source(ob.extract()?))
589 }
590}
591
592impl std::fmt::Display for Control {
593 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
594 self.0.fmt(f)
595 }
596}
597
598pub struct Binary(deb822_lossless::Paragraph);
600
601impl From<Binary> for deb822_lossless::Paragraph {
602 fn from(b: Binary) -> Self {
603 b.0
604 }
605}
606
607impl From<deb822_lossless::Paragraph> for Binary {
608 fn from(p: deb822_lossless::Paragraph) -> Self {
609 Binary(p)
610 }
611}
612
613#[cfg(feature = "python-debian")]
614impl pyo3::ToPyObject for Binary {
615 fn to_object(&self, py: pyo3::Python) -> pyo3::PyObject {
616 self.0.to_object(py)
617 }
618}
619
620#[cfg(feature = "python-debian")]
621impl pyo3::FromPyObject<'_> for Binary {
622 fn extract_bound(ob: &pyo3::Bound<pyo3::PyAny>) -> pyo3::PyResult<Self> {
623 use pyo3::prelude::*;
624 Ok(Binary(ob.extract()?))
625 }
626}
627
628impl Default for Binary {
629 fn default() -> Self {
630 Self::new()
631 }
632}
633
634impl Binary {
635 pub fn new() -> Self {
637 Binary(deb822_lossless::Paragraph::new())
638 }
639
640 pub fn as_mut_deb822(&mut self) -> &mut deb822_lossless::Paragraph {
642 &mut self.0
643 }
644
645 pub fn as_deb822(&self) -> &deb822_lossless::Paragraph {
647 &self.0
648 }
649
650 pub fn wrap_and_sort(
652 &mut self,
653 indentation: deb822_lossless::Indentation,
654 immediate_empty_line: bool,
655 max_line_length_one_liner: Option<usize>,
656 ) {
657 self.0 = self.0.wrap_and_sort(
658 indentation,
659 immediate_empty_line,
660 max_line_length_one_liner,
661 None,
662 Some(&format_field),
663 );
664 }
665
666 pub fn name(&self) -> Option<String> {
668 self.0.get("Package")
669 }
670
671 pub fn set_name(&mut self, name: &str) {
673 self.0.set("Package", name);
674 }
675
676 pub fn section(&self) -> Option<String> {
678 self.0.get("Section")
679 }
680
681 pub fn set_section(&mut self, section: Option<&str>) {
683 if let Some(section) = section {
684 self.0.set("Section", section);
685 } else {
686 self.0.remove("Section");
687 }
688 }
689
690 pub fn priority(&self) -> Option<Priority> {
692 self.0.get("Priority").and_then(|v| v.parse().ok())
693 }
694
695 pub fn set_priority(&mut self, priority: Option<Priority>) {
697 if let Some(priority) = priority {
698 self.0.set("Priority", priority.to_string().as_str());
699 } else {
700 self.0.remove("Priority");
701 }
702 }
703
704 pub fn architecture(&self) -> Option<String> {
706 self.0.get("Architecture")
707 }
708
709 pub fn set_architecture(&mut self, arch: Option<&str>) {
711 if let Some(arch) = arch {
712 self.0.set("Architecture", arch);
713 } else {
714 self.0.remove("Architecture");
715 }
716 }
717
718 pub fn depends(&self) -> Option<Relations> {
720 self.0.get("Depends").map(|s| s.parse().unwrap())
721 }
722
723 pub fn set_depends(&mut self, depends: Option<&Relations>) {
725 if let Some(depends) = depends {
726 self.0.set("Depends", depends.to_string().as_str());
727 } else {
728 self.0.remove("Depends");
729 }
730 }
731
732 pub fn recommends(&self) -> Option<Relations> {
734 self.0.get("Recommends").map(|s| s.parse().unwrap())
735 }
736
737 pub fn set_recommends(&mut self, recommends: Option<&Relations>) {
739 if let Some(recommends) = recommends {
740 self.0.set("Recommends", recommends.to_string().as_str());
741 } else {
742 self.0.remove("Recommends");
743 }
744 }
745
746 pub fn suggests(&self) -> Option<Relations> {
748 self.0.get("Suggests").map(|s| s.parse().unwrap())
749 }
750
751 pub fn set_suggests(&mut self, suggests: Option<&Relations>) {
753 if let Some(suggests) = suggests {
754 self.0.set("Suggests", suggests.to_string().as_str());
755 } else {
756 self.0.remove("Suggests");
757 }
758 }
759
760 pub fn enhances(&self) -> Option<Relations> {
762 self.0.get("Enhances").map(|s| s.parse().unwrap())
763 }
764
765 pub fn set_enhances(&mut self, enhances: Option<&Relations>) {
767 if let Some(enhances) = enhances {
768 self.0.set("Enhances", enhances.to_string().as_str());
769 } else {
770 self.0.remove("Enhances");
771 }
772 }
773
774 pub fn pre_depends(&self) -> Option<Relations> {
776 self.0.get("Pre-Depends").map(|s| s.parse().unwrap())
777 }
778
779 pub fn set_pre_depends(&mut self, pre_depends: Option<&Relations>) {
781 if let Some(pre_depends) = pre_depends {
782 self.0.set("Pre-Depends", pre_depends.to_string().as_str());
783 } else {
784 self.0.remove("Pre-Depends");
785 }
786 }
787
788 pub fn breaks(&self) -> Option<Relations> {
790 self.0.get("Breaks").map(|s| s.parse().unwrap())
791 }
792
793 pub fn set_breaks(&mut self, breaks: Option<&Relations>) {
795 if let Some(breaks) = breaks {
796 self.0.set("Breaks", breaks.to_string().as_str());
797 } else {
798 self.0.remove("Breaks");
799 }
800 }
801
802 pub fn conflicts(&self) -> Option<Relations> {
804 self.0.get("Conflicts").map(|s| s.parse().unwrap())
805 }
806
807 pub fn set_conflicts(&mut self, conflicts: Option<&Relations>) {
809 if let Some(conflicts) = conflicts {
810 self.0.set("Conflicts", conflicts.to_string().as_str());
811 } else {
812 self.0.remove("Conflicts");
813 }
814 }
815
816 pub fn replaces(&self) -> Option<Relations> {
818 self.0.get("Replaces").map(|s| s.parse().unwrap())
819 }
820
821 pub fn set_replaces(&mut self, replaces: Option<&Relations>) {
823 if let Some(replaces) = replaces {
824 self.0.set("Replaces", replaces.to_string().as_str());
825 } else {
826 self.0.remove("Replaces");
827 }
828 }
829
830 pub fn provides(&self) -> Option<Relations> {
832 self.0.get("Provides").map(|s| s.parse().unwrap())
833 }
834
835 pub fn set_provides(&mut self, provides: Option<&Relations>) {
837 if let Some(provides) = provides {
838 self.0.set("Provides", provides.to_string().as_str());
839 } else {
840 self.0.remove("Provides");
841 }
842 }
843
844 pub fn built_using(&self) -> Option<Relations> {
846 self.0.get("Built-Using").map(|s| s.parse().unwrap())
847 }
848
849 pub fn set_built_using(&mut self, built_using: Option<&Relations>) {
851 if let Some(built_using) = built_using {
852 self.0.set("Built-Using", built_using.to_string().as_str());
853 } else {
854 self.0.remove("Built-Using");
855 }
856 }
857
858 pub fn multi_arch(&self) -> Option<MultiArch> {
860 self.0.get("Multi-Arch").map(|s| s.parse().unwrap())
861 }
862
863 pub fn set_multi_arch(&mut self, multi_arch: Option<MultiArch>) {
865 if let Some(multi_arch) = multi_arch {
866 self.0.set("Multi-Arch", multi_arch.to_string().as_str());
867 } else {
868 self.0.remove("Multi-Arch");
869 }
870 }
871
872 pub fn essential(&self) -> bool {
874 self.0.get("Essential").map(|s| s == "yes").unwrap_or(false)
875 }
876
877 pub fn set_essential(&mut self, essential: bool) {
879 if essential {
880 self.0.set("Essential", "yes");
881 } else {
882 self.0.remove("Essential");
883 }
884 }
885
886 pub fn description(&self) -> Option<String> {
888 self.0.get("Description")
889 }
890
891 pub fn set_description(&mut self, description: Option<&str>) {
893 if let Some(description) = description {
894 self.0.set("Description", description);
895 } else {
896 self.0.remove("Description");
897 }
898 }
899
900 pub fn homepage(&self) -> Option<url::Url> {
902 self.0.get("Homepage").and_then(|s| s.parse().ok())
903 }
904
905 pub fn set_homepage(&mut self, url: &url::Url) {
907 self.0.set("Homepage", url.as_str());
908 }
909}
910
911#[cfg(test)]
912mod tests {
913 use super::*;
914 use crate::relations::VersionConstraint;
915 #[test]
916 fn test_parse() {
917 let control: Control = r#"Source: foo
918Section: libs
919Priority: optional
920Build-Depends: bar (>= 1.0.0), baz (>= 1.0.0)
921Homepage: https://example.com
922
923"#
924 .parse()
925 .unwrap();
926 let source = control.source().unwrap();
927
928 assert_eq!(source.name(), Some("foo".to_owned()));
929 assert_eq!(source.section(), Some("libs".to_owned()));
930 assert_eq!(source.priority(), Some(super::Priority::Optional));
931 assert_eq!(
932 source.homepage(),
933 Some("https://example.com".parse().unwrap())
934 );
935 let bd = source.build_depends().unwrap();
936 let entries = bd.entries().collect::<Vec<_>>();
937 assert_eq!(entries.len(), 2);
938 let rel = entries[0].relations().collect::<Vec<_>>().pop().unwrap();
939 assert_eq!(rel.name(), "bar");
940 assert_eq!(
941 rel.version(),
942 Some((
943 VersionConstraint::GreaterThanEqual,
944 "1.0.0".parse().unwrap()
945 ))
946 );
947 let rel = entries[1].relations().collect::<Vec<_>>().pop().unwrap();
948 assert_eq!(rel.name(), "baz");
949 assert_eq!(
950 rel.version(),
951 Some((
952 VersionConstraint::GreaterThanEqual,
953 "1.0.0".parse().unwrap()
954 ))
955 );
956 }
957
958 #[test]
959 fn test_description() {
960 let control: Control = r#"Source: foo
961
962Package: foo
963Description: this is the short description
964 And the longer one
965 .
966 is on the next lines
967"#
968 .parse()
969 .unwrap();
970 let binary = control.binaries().next().unwrap();
971 assert_eq!(
972 binary.description(),
973 Some(
974 "this is the short description\nAnd the longer one\n.\nis on the next lines"
975 .to_owned()
976 )
977 );
978 }
979
980 #[test]
981 fn test_as_mut_deb822() {
982 let mut control = Control::new();
983 let deb822 = control.as_mut_deb822();
984 let mut p = deb822.add_paragraph();
985 p.set("Source", "foo");
986 assert_eq!(control.source().unwrap().name(), Some("foo".to_owned()));
987 }
988
989 #[test]
990 fn test_as_deb822() {
991 let control = Control::new();
992 let _deb822: &deb822_lossless::Deb822 = control.as_deb822();
993 }
994
995 #[test]
996 fn test_set_depends() {
997 let mut control = Control::new();
998 let mut binary = control.add_binary("foo");
999 let relations: Relations = "bar (>= 1.0.0)".parse().unwrap();
1000 binary.set_depends(Some(&relations));
1001 }
1002
1003 #[test]
1004 fn test_wrap_and_sort() {
1005 let mut control: Control = r#"Package: blah
1006Section: libs
1007
1008
1009
1010Package: foo
1011Description: this is a
1012 bar
1013 blah
1014"#
1015 .parse()
1016 .unwrap();
1017 control.wrap_and_sort(deb822_lossless::Indentation::Spaces(2), false, None);
1018 let expected = r#"Package: blah
1019Section: libs
1020
1021Package: foo
1022Description: this is a
1023 bar
1024 blah
1025"#
1026 .to_owned();
1027 assert_eq!(control.to_string(), expected);
1028 }
1029
1030 #[test]
1031 fn test_wrap_and_sort_source() {
1032 let mut control: Control = r#"Source: blah
1033Depends: foo, bar (<= 1.0.0)
1034
1035"#
1036 .parse()
1037 .unwrap();
1038 control.wrap_and_sort(deb822_lossless::Indentation::Spaces(2), true, None);
1039 let expected = r#"Source: blah
1040Depends: bar (<= 1.0.0), foo
1041"#
1042 .to_owned();
1043 assert_eq!(control.to_string(), expected);
1044 }
1045}