#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum ValidationSeverity {
Warning,
Error,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ValidationCategory {
MissingPart,
Relationship,
ContentType,
Presentation,
SlideMaster,
Slide,
Chart,
Xml,
Theme,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PackageValidationIssue {
pub category: ValidationCategory,
pub severity: ValidationSeverity,
pub message: String,
pub path: Option<String>,
}
impl PackageValidationIssue {
pub fn error(
category: ValidationCategory,
message: impl Into<String>,
path: Option<&str>,
) -> Self {
Self {
category,
severity: ValidationSeverity::Error,
message: message.into(),
path: path.map(str::to_string),
}
}
pub fn warning(
category: ValidationCategory,
message: impl Into<String>,
path: Option<&str>,
) -> Self {
Self {
category,
severity: ValidationSeverity::Warning,
message: message.into(),
path: path.map(str::to_string),
}
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct PackageValidationReport {
pub issues: Vec<PackageValidationIssue>,
}
impl PackageValidationReport {
pub fn is_valid(&self) -> bool {
self.issues
.iter()
.all(|i| i.severity != ValidationSeverity::Error)
}
pub fn is_ok(&self) -> bool {
self.is_valid()
}
pub fn error_count(&self) -> usize {
self.issues
.iter()
.filter(|i| i.severity == ValidationSeverity::Error)
.count()
}
pub fn warning_count(&self) -> usize {
self.issues
.iter()
.filter(|i| i.severity == ValidationSeverity::Warning)
.count()
}
pub fn push(&mut self, issue: PackageValidationIssue) {
self.issues.push(issue);
}
pub fn extend(&mut self, issues: impl IntoIterator<Item = PackageValidationIssue>) {
self.issues.extend(issues);
}
pub fn error_messages(&self) -> Vec<String> {
self.issues
.iter()
.filter(|i| i.severity == ValidationSeverity::Error)
.map(|i| i.message.clone())
.collect()
}
pub fn issues_in_category(
&self,
category: ValidationCategory,
) -> impl Iterator<Item = &PackageValidationIssue> {
self.issues
.iter()
.filter(move |i| i.category == category)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn counts_errors_and_warnings() {
let mut report = PackageValidationReport::default();
report.push(PackageValidationIssue::error(
ValidationCategory::Presentation,
"bad",
Some("ppt/presentation.xml"),
));
report.push(PackageValidationIssue::warning(
ValidationCategory::Theme,
"soft",
None,
));
assert_eq!(report.error_count(), 1);
assert_eq!(report.warning_count(), 1);
assert!(!report.is_valid());
}
}