ppt_rs/core/package_validation/
report.rs1#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
5pub enum ValidationSeverity {
6 Warning,
7 Error,
8}
9
10#[derive(Clone, Copy, Debug, PartialEq, Eq)]
12pub enum ValidationCategory {
13 MissingPart,
14 Relationship,
15 ContentType,
16 Presentation,
17 SlideMaster,
18 Slide,
19 Chart,
20 Xml,
21 Theme,
22}
23
24#[derive(Clone, Debug, PartialEq, Eq)]
26pub struct PackageValidationIssue {
27 pub category: ValidationCategory,
28 pub severity: ValidationSeverity,
29 pub message: String,
30 pub path: Option<String>,
32}
33
34impl PackageValidationIssue {
35 pub fn error(
36 category: ValidationCategory,
37 message: impl Into<String>,
38 path: Option<&str>,
39 ) -> Self {
40 Self {
41 category,
42 severity: ValidationSeverity::Error,
43 message: message.into(),
44 path: path.map(str::to_string),
45 }
46 }
47
48 pub fn warning(
49 category: ValidationCategory,
50 message: impl Into<String>,
51 path: Option<&str>,
52 ) -> Self {
53 Self {
54 category,
55 severity: ValidationSeverity::Warning,
56 message: message.into(),
57 path: path.map(str::to_string),
58 }
59 }
60}
61
62#[derive(Clone, Debug, Default, PartialEq, Eq)]
64pub struct PackageValidationReport {
65 pub issues: Vec<PackageValidationIssue>,
66}
67
68impl PackageValidationReport {
69 pub fn is_valid(&self) -> bool {
70 self.issues
71 .iter()
72 .all(|i| i.severity != ValidationSeverity::Error)
73 }
74
75 pub fn is_ok(&self) -> bool {
76 self.is_valid()
77 }
78
79 pub fn error_count(&self) -> usize {
80 self.issues
81 .iter()
82 .filter(|i| i.severity == ValidationSeverity::Error)
83 .count()
84 }
85
86 pub fn warning_count(&self) -> usize {
87 self.issues
88 .iter()
89 .filter(|i| i.severity == ValidationSeverity::Warning)
90 .count()
91 }
92
93 pub fn push(&mut self, issue: PackageValidationIssue) {
94 self.issues.push(issue);
95 }
96
97 pub fn extend(&mut self, issues: impl IntoIterator<Item = PackageValidationIssue>) {
98 self.issues.extend(issues);
99 }
100
101 pub fn error_messages(&self) -> Vec<String> {
103 self.issues
104 .iter()
105 .filter(|i| i.severity == ValidationSeverity::Error)
106 .map(|i| i.message.clone())
107 .collect()
108 }
109
110 pub fn issues_in_category(
111 &self,
112 category: ValidationCategory,
113 ) -> impl Iterator<Item = &PackageValidationIssue> {
114 self.issues
115 .iter()
116 .filter(move |i| i.category == category)
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123
124 #[test]
125 fn counts_errors_and_warnings() {
126 let mut report = PackageValidationReport::default();
127 report.push(PackageValidationIssue::error(
128 ValidationCategory::Presentation,
129 "bad",
130 Some("ppt/presentation.xml"),
131 ));
132 report.push(PackageValidationIssue::warning(
133 ValidationCategory::Theme,
134 "soft",
135 None,
136 ));
137 assert_eq!(report.error_count(), 1);
138 assert_eq!(report.warning_count(), 1);
139 assert!(!report.is_valid());
140 }
141}