1use anyhow::Result;
2use libverify_core::assessment::{AssessmentReport, BatchEntry, BatchReport, VerificationResult};
3use libverify_core::profile::GateDecision;
4
5pub fn render(result: &VerificationResult, only_failures: bool) -> Result<String> {
6 if only_failures {
7 let filtered = filter_result(result);
8 Ok(serde_json::to_string_pretty(&filtered)?)
9 } else {
10 Ok(serde_json::to_string_pretty(result)?)
11 }
12}
13
14pub fn render_batch(batch: &BatchReport, only_failures: bool) -> Result<String> {
15 if only_failures {
16 let filtered = filter_batch(batch);
17 Ok(serde_json::to_string_pretty(&filtered)?)
18 } else {
19 Ok(serde_json::to_string_pretty(batch)?)
20 }
21}
22
23fn filter_result(result: &VerificationResult) -> VerificationResult {
24 let report = &result.report;
25 let mut filtered_findings = Vec::new();
26 let mut filtered_outcomes = Vec::new();
27
28 for (finding, outcome) in report.findings.iter().zip(report.outcomes.iter()) {
29 if outcome.decision == GateDecision::Fail {
30 filtered_findings.push(finding.clone());
31 filtered_outcomes.push(outcome.clone());
32 }
33 }
34
35 VerificationResult {
36 report: AssessmentReport {
37 profile_name: report.profile_name.clone(),
38 findings: filtered_findings,
39 outcomes: filtered_outcomes,
40 severity_labels: report.severity_labels.clone(),
41 },
42 evidence: result.evidence.clone(),
43 }
44}
45
46fn filter_batch(batch: &BatchReport) -> BatchReport {
47 BatchReport {
48 reports: batch
49 .reports
50 .iter()
51 .map(|entry| BatchEntry {
52 subject_id: entry.subject_id.clone(),
53 result: filter_result(&entry.result),
54 })
55 .collect(),
56 total_pass: batch.total_pass,
57 total_review: batch.total_review,
58 total_fail: batch.total_fail,
59 skipped: batch.skipped.clone(),
60 }
61}