mod display;
pub mod error;
mod value_object;
pub use error::{ReportError, ReportResult};
use crate::report::value_object::metric::ReportMetric;
use crate::severity::Severity;
use crate::violation::Violation;
use std::cmp::PartialEq;
#[derive(Debug, Clone, PartialEq, serde::Serialize)]
pub struct Report {
violations: Vec<Violation>,
metrics: ReportMetric,
}
impl Report {
pub fn new() -> Self {
Self {
violations: Vec::new(),
metrics: Default::default(),
}
}
pub fn validate(&self) -> ReportResult<()> {
for (i, v) in self.violations.iter().enumerate() {
v.validate()
.map_err(|e| ReportError::invalid_violation(i, e))?;
}
Ok(())
}
pub fn from_violations(violations: Vec<Violation>) -> Self {
Self {
violations,
metrics: Default::default(),
}
}
pub fn metrics(&self) -> &ReportMetric {
&self.metrics
}
pub fn set_violations(&mut self, violations: Vec<Violation>) {
self.violations = violations;
}
pub fn metrics_mut(&mut self) -> &mut ReportMetric {
&mut self.metrics
}
pub fn set_metrics(&mut self, metrics: ReportMetric) {
self.metrics = metrics;
}
pub fn violations(&self) -> &[Violation] {
&self.violations
}
pub fn into_violations(self) -> Vec<Violation> {
self.violations
}
pub fn push(&mut self, violation: Violation) {
self.violations.push(violation);
}
pub fn extend<I>(&mut self, violations: I)
where
I: IntoIterator<Item = Violation>,
{
self.violations.extend(violations);
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.violations.is_empty()
}
#[must_use]
pub fn len(&self) -> usize {
self.violations.len()
}
#[must_use]
pub fn failed(&self) -> bool {
self.violations.iter().any(|v| v.severity().is_error())
}
#[must_use]
pub fn has_errors(&self) -> bool {
self.violations
.iter()
.any(|v| matches!(v.severity(), Severity::Error))
}
#[must_use]
pub fn has_warnings(&self) -> bool {
self.violations
.iter()
.any(|v| v.severity() == Severity::Warn)
}
#[must_use]
pub fn count_by_severity(&self, severity: Severity) -> usize {
self.violations
.iter()
.filter(|v| v.severity() == severity)
.count()
}
#[must_use]
pub fn error_count(&self) -> usize {
self.count_by_severity(Severity::Error)
}
#[must_use]
pub fn warn_count(&self) -> usize {
self.count_by_severity(Severity::Warn)
}
#[must_use]
pub fn info_count(&self) -> usize {
self.count_by_severity(Severity::Info)
}
pub fn iter(&self) -> impl Iterator<Item = &Violation> {
self.violations.iter()
}
pub fn errors(&self) -> impl Iterator<Item = &Violation> {
self.violations
.iter()
.filter(|v| matches!(v.severity(), Severity::Error))
}
pub fn warnings(&self) -> impl Iterator<Item = &Violation> {
self.violations
.iter()
.filter(|v| v.severity() == Severity::Warn)
}
}
impl Default for Report {
fn default() -> Self {
Self::new()
}
}