use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use crate::{Severity, ValidationReport};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum RuleSeverity {
Off,
Info,
Warn,
Error,
Critical,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct RulesConfig(pub HashMap<String, RuleSeverity>);
fn rule_matches(code: &str, key: &str) -> bool {
code == key || code.rsplit('/').next() == Some(key)
}
impl ValidationReport {
pub fn apply_rules(mut self, rules: &RulesConfig) -> Self {
if rules.0.is_empty() {
return self;
}
let all: Vec<_> = self
.critical
.drain(..)
.chain(self.errors.drain(..))
.chain(self.warnings.drain(..))
.chain(self.info.drain(..))
.collect();
for mut issue in all {
let override_sev = rules
.0
.iter()
.find(|(k, _)| rule_matches(&issue.code, k))
.map(|(_, v)| v);
match override_sev {
Some(RuleSeverity::Off) => {} Some(RuleSeverity::Info) => {
issue.severity = Severity::Info;
self.info.push(issue);
}
Some(RuleSeverity::Warn) => {
issue.severity = Severity::Warning;
self.warnings.push(issue);
}
Some(RuleSeverity::Error) => {
issue.severity = Severity::Error;
self.errors.push(issue);
}
Some(RuleSeverity::Critical) => {
issue.severity = Severity::Critical;
self.critical.push(issue);
}
None => match issue.severity {
Severity::Critical => self.critical.push(issue),
Severity::Error => self.errors.push(issue),
Severity::Warning => self.warnings.push(issue),
Severity::Info => self.info.push(issue),
},
}
}
self.is_playable = self.critical.is_empty();
self.is_compliant = self.critical.is_empty() && self.errors.is_empty();
self
}
}