a2a_protocol_server/conformance/
report.rs1use std::fmt;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12#[non_exhaustive]
13pub enum Outcome {
14 Pass,
16 Fail,
18 NotApplicable,
21}
22
23#[derive(Debug, Clone)]
25#[non_exhaustive]
26pub struct CheckResult {
27 pub name: &'static str,
29 pub outcome: Outcome,
31 pub detail: String,
34}
35
36impl CheckResult {
37 pub(super) fn pass(name: &'static str, detail: impl Into<String>) -> Self {
38 Self {
39 name,
40 outcome: Outcome::Pass,
41 detail: detail.into(),
42 }
43 }
44 pub(super) fn fail(name: &'static str, detail: impl Into<String>) -> Self {
45 Self {
46 name,
47 outcome: Outcome::Fail,
48 detail: detail.into(),
49 }
50 }
51 pub(super) fn skip(name: &'static str, detail: impl Into<String>) -> Self {
52 Self {
53 name,
54 outcome: Outcome::NotApplicable,
55 detail: detail.into(),
56 }
57 }
58}
59
60#[derive(Debug, Clone)]
62pub struct Report {
63 pub(super) results: Vec<CheckResult>,
64}
65
66impl Report {
67 #[must_use]
69 pub fn results(&self) -> &[CheckResult] {
70 &self.results
71 }
72
73 #[must_use]
75 pub fn graded(&self) -> usize {
76 self.results
77 .iter()
78 .filter(|r| r.outcome != Outcome::NotApplicable)
79 .count()
80 }
81
82 #[must_use]
84 pub fn passed(&self) -> usize {
85 self.results
86 .iter()
87 .filter(|r| r.outcome == Outcome::Pass)
88 .count()
89 }
90
91 #[must_use]
93 pub fn failed(&self) -> usize {
94 self.graded() - self.passed()
95 }
96
97 #[must_use]
102 pub fn is_pass(&self) -> bool {
103 self.graded() > 0 && self.failed() == 0
104 }
105
106 pub fn assert_pass(&self) {
112 assert!(self.is_pass(), "{self}");
113 }
114}
115
116impl fmt::Display for Report {
117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118 writeln!(f, "executor conformance:")?;
119 for r in &self.results {
120 let mark = match r.outcome {
121 Outcome::Pass => "pass",
122 Outcome::Fail => "FAIL",
123 Outcome::NotApplicable => "n/a ",
124 };
125 writeln!(f, " {mark} {:<34} {}", r.name, r.detail)?;
126 }
127 write!(
128 f,
129 " {} of {} graded checks passed, {} not applicable",
130 self.passed(),
131 self.graded(),
132 self.results.len() - self.graded()
133 )
134 }
135}