mcp_trace_validator/report/
human.rs1use core::fmt::Write as _;
11
12use super::{Outcome, Report};
13
14impl Report {
15 #[must_use]
17 pub fn render_human(&self) -> String {
18 let mut out = String::new();
19 let _ = writeln!(out, "MCP trace validation — revision {}", self.revision);
20 self.write_revision_mismatch(&mut out);
21 for row in &self.requirements {
22 let marker = match row.outcome {
23 Outcome::Pass => "PASS",
24 Outcome::Fail => "FAIL",
25 Outcome::Warn => "WARN",
26 Outcome::Excluded => "EXCL",
27 Outcome::Unsupported => "UNSUP",
28 Outcome::NotApplicable => "N/A",
29 Outcome::NotObserved => "NOBS",
30 };
31 let _ = writeln!(out, " {marker:<5} {} ({})", row.id, row.level);
32 for finding in &row.findings {
33 match finding.seq {
34 Some(seq) => {
35 let _ = writeln!(out, " seq {seq}: {}", finding.detail);
36 }
37 None => {
38 let _ = writeln!(out, " {}", finding.detail);
39 }
40 }
41 }
42 if let Some(exclusion) = &row.exclusion {
43 let _ = writeln!(out, " excluded: {exclusion}");
44 }
45 for check in &row.missing_checks {
46 let _ = writeln!(out, " unsupported check: {check}");
47 }
48 if let Some(capability) = &row.capability {
49 let _ = writeln!(
50 out,
51 " not applicable: capability {capability} was not declared in this session"
52 );
53 }
54 if row.outcome == Outcome::NotObserved {
55 let _ = writeln!(
56 out,
57 " not observed: the session carried none of the traffic this clause binds to"
58 );
59 }
60 }
61 let _ = writeln!(out, "totals: {}", self.totals);
65 let _ = writeln!(out, "verdict: {}", self.verdict());
66 self.write_revision_mismatch(&mut out);
67 out
68 }
69
70 fn write_revision_mismatch(&self, out: &mut String) {
77 let Some(declared) = &self.revision_mismatch else {
78 return;
79 };
80 let subject = if declared.len() == 1 {
81 "revision"
82 } else {
83 "revisions"
84 };
85 let suggestion = declared.last().map_or("<revision>", String::as_str);
86 let _ = writeln!(
87 out,
88 " NOTE this session declares protocol {subject} {}, not {}.",
89 declared.join(", "),
90 self.revision
91 );
92 let _ = writeln!(
93 out,
94 " Every outcome here judges it against rules it was not playing by;"
95 );
96 let _ = writeln!(
97 out,
98 " re-run with `--revision {suggestion}` to judge it against its own."
99 );
100 }
101}