use crate::error::Error;
use crate::spec::SPEC_COMMIT;
use crate::{FileLintResult, LintReport, Severity, Violation};
use serde::Serialize;
#[derive(Debug, Serialize)]
pub struct ReportViolation {
pub severity: String,
pub field: String,
pub message: String,
pub spec_ref: String,
}
#[derive(Debug, Serialize)]
pub struct FileReport {
pub path: String,
pub valid: bool,
pub violations: Vec<ReportViolation>,
}
#[derive(Debug, Serialize)]
pub struct AggregateReport {
pub spec_commit: String,
pub valid: bool,
pub files: Vec<FileReport>,
}
#[derive(Debug, Serialize)]
pub struct SingleFileReport {
pub spec_commit: String,
pub valid: bool,
pub violations: Vec<ReportViolation>,
}
impl From<&Violation> for ReportViolation {
fn from(v: &Violation) -> Self {
Self {
severity: match v.severity {
Severity::Warn => "warn".to_string(),
Severity::Error => "error".to_string(),
},
field: v.field.clone(),
message: v.message.clone(),
spec_ref: v.spec_ref.to_string(),
}
}
}
pub fn report_to_yaml_single(report: &LintReport) -> Result<String, Error> {
let doc = SingleFileReport {
spec_commit: SPEC_COMMIT.to_string(),
valid: report.valid,
violations: report.violations.iter().map(Into::into).collect(),
};
serde_saphyr::to_string(&doc).map_err(|e| Error::Yaml(e.to_string()))
}
pub fn report_to_yaml_aggregate(results: &[FileLintResult]) -> Result<String, Error> {
let files = results
.iter()
.map(|r| FileReport {
path: r.path.display().to_string(),
valid: r.report.valid,
violations: r.report.violations.iter().map(Into::into).collect(),
})
.collect();
let doc = AggregateReport {
spec_commit: SPEC_COMMIT.to_string(),
valid: aggregate_valid(results),
files,
};
serde_saphyr::to_string(&doc).map_err(|e| Error::Yaml(e.to_string()))
}
fn aggregate_valid(results: &[FileLintResult]) -> bool {
results.iter().all(|r| r.report.valid)
}