persistant_core/
verdict.rs1use crate::{CapabilityId, Config, Reason, Row};
3use std::collections::BTreeMap;
4use std::fmt;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10#[non_exhaustive]
11pub enum Verdict {
12 Exact,
14 EquallyCorrectButDifferent,
19 Wrong,
21 Missing,
23}
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27pub struct Controls {
28 pub positive_passed: bool,
30 pub known_bad_failed: bool,
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq)]
36pub struct ControlsNotRun(pub Controls);
37
38impl fmt::Display for ControlsNotRun {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 write!(
41 f,
42 "an exact result is not recorded as on without both controls (positive passed: {}, known-bad failed: {})",
43 self.0.positive_passed, self.0.known_bad_failed
44 )
45 }
46}
47
48impl std::error::Error for ControlsNotRun {}
49
50impl Verdict {
51 pub fn into_row(
56 self,
57 subject: CapabilityId,
58 backend: impl Into<String>,
59 version: impl Into<String>,
60 config: Config,
61 metadata: Config,
62 controls: Controls,
63 ) -> Result<Row, ControlsNotRun> {
64 let (enabled, reason, note) = match self {
65 Verdict::Exact => {
66 if !(controls.positive_passed && controls.known_bad_failed) {
67 return Err(ControlsNotRun(controls));
68 }
69 (true, None, "")
70 }
71 Verdict::EquallyCorrectButDifferent => (
72 false,
73 Some(Reason::Wrong),
74 "equally correct but different: widen the test only if stricter than the contract, else mint a leaf",
75 ),
76 Verdict::Wrong => (false, Some(Reason::Wrong), ""),
77 Verdict::Missing => (false, Some(Reason::Missing), ""),
78 };
79 Ok(Row {
80 subject_kind: "capability".to_string(),
81 subject,
82 backend: backend.into(),
83 version: version.into(),
84 config,
85 enabled,
86 reason,
87 metadata,
88 note: note.to_string(),
89 extra: BTreeMap::new(),
90 })
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97
98 fn row(v: Verdict, c: Controls) -> Result<Row, ControlsNotRun> {
99 v.into_row(
100 CapabilityId::new("kv.put_if_absent").unwrap(),
101 "sqlite",
102 "3.46",
103 Config::new(),
104 Config::new().with("test", "kv::put_if_absent_race"),
105 c,
106 )
107 }
108
109 const BOTH: Controls = Controls {
110 positive_passed: true,
111 known_bad_failed: true,
112 };
113
114 #[test]
115 fn exact_is_on_only_with_both_controls() {
116 let r = row(Verdict::Exact, BOTH).unwrap();
117 assert!(r.enabled && r.reason.is_none());
118 let no_known_bad = Controls {
119 known_bad_failed: false,
120 ..BOTH
121 };
122 assert_eq!(
123 row(Verdict::Exact, no_known_bad),
124 Err(ControlsNotRun(no_known_bad))
125 );
126 let no_positive = Controls {
127 positive_passed: false,
128 ..BOTH
129 };
130 assert!(row(Verdict::Exact, no_positive).is_err());
131 }
132
133 #[test]
134 fn everything_else_is_off_with_the_right_reason_and_needs_no_controls() {
135 let none = Controls {
136 positive_passed: false,
137 known_bad_failed: false,
138 };
139 assert_eq!(
140 row(Verdict::Wrong, none).unwrap().reason,
141 Some(Reason::Wrong)
142 );
143 assert_eq!(
144 row(Verdict::Missing, none).unwrap().reason,
145 Some(Reason::Missing)
146 );
147 let e = row(Verdict::EquallyCorrectButDifferent, none).unwrap();
148 assert!(!e.enabled && e.reason == Some(Reason::Wrong) && e.note.contains("mint a leaf"));
149 }
150}