#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Severity {
Error,
Warning,
Fyi,
}
impl Severity {
#[must_use]
pub fn as_str(self) -> &'static str {
match self {
Severity::Error => "error",
Severity::Warning => "warning",
Severity::Fyi => "fyi",
}
}
}
pub struct Finding {
pub(crate) rule: String,
pub(crate) group: String,
pub(crate) description: String,
pub(crate) line: Option<u32>,
pub(crate) severity: Severity,
}
impl Finding {
#[must_use]
pub fn rule(&self) -> &str {
&self.rule
}
#[must_use]
pub fn group(&self) -> &str {
&self.group
}
#[must_use]
pub fn description(&self) -> &str {
&self.description
}
#[must_use]
pub fn line(&self) -> Option<u32> {
self.line
}
#[must_use]
pub fn severity(&self) -> Severity {
self.severity
}
}
pub struct Report {
pub(crate) findings: Vec<Finding>,
pub(crate) certified: bool,
pub(crate) revalidate_reason: Option<String>,
}
impl Report {
#[must_use]
pub fn is_valid(&self) -> bool {
!self.findings.iter().any(|f| f.severity == Severity::Error)
}
#[must_use]
pub fn findings(&self) -> &[Finding] {
&self.findings
}
#[must_use]
pub fn certified(&self) -> bool {
self.certified
}
#[must_use]
pub fn revalidate_reason(&self) -> Option<&str> {
self.revalidate_reason.as_deref()
}
#[must_use]
pub fn count(&self, severity: Severity) -> usize {
self.findings
.iter()
.filter(|f| f.severity == severity)
.count()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.findings.is_empty()
}
}
impl std::fmt::Debug for Finding {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Finding")
.field("rule", &self.rule)
.field("group", &self.group)
.field("line", &self.line)
.field("severity", &self.severity)
.field("description", &self.description)
.finish()
}
}
impl std::fmt::Debug for Report {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Report")
.field("valid", &self.is_valid())
.field("errors", &self.count(Severity::Error))
.field("warnings", &self.count(Severity::Warning))
.field("fyi", &self.count(Severity::Fyi))
.finish()
}
}