use crate::proof_gate_registry::ProofGate;
use std::collections::HashSet;
#[derive(Debug, Default, Clone)]
pub struct UnverifiedRun {
passed_gates: HashSet<ProofGate>,
}
#[derive(Debug, Clone)]
pub struct VerifiedRun {
passed_gates: HashSet<ProofGate>,
}
impl UnverifiedRun {
pub fn new() -> Self {
Self {
passed_gates: HashSet::new(),
}
}
pub fn mark_gate_passed(&mut self, gate: ProofGate) {
self.passed_gates.insert(gate);
}
pub fn gate_passed(&self, gate: ProofGate) -> bool {
self.passed_gates.contains(&gate)
}
pub fn passed_gates(&self) -> Vec<ProofGate> {
self.passed_gates.iter().copied().collect()
}
pub fn verify(self) -> Result<VerifiedRun, String> {
if self
.passed_gates
.contains(&ProofGate::gate_test_suite_passes)
{
Ok(VerifiedRun {
passed_gates: self.passed_gates,
})
} else {
Err(format!(
"Cannot verify run: {} gate not passed. Required gates: {}",
ProofGate::gate_test_suite_passes,
ProofGate::pipeline_order()
.iter()
.map(|g| g.label())
.collect::<Vec<_>>()
.join(", ")
))
}
}
}
impl VerifiedRun {
pub fn passed_gates(&self) -> Vec<ProofGate> {
self.passed_gates.iter().copied().collect()
}
pub fn export_results(&self) -> String {
format!(
"Exporting results verified with {} gates: {:?}",
self.passed_gates.len(),
self.passed_gates
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_typestate_lifecycle() {
let mut run = UnverifiedRun::new();
assert!(!run.gate_passed(ProofGate::gate_test_suite_passes));
run.mark_gate_passed(ProofGate::gate_test_suite_passes);
assert!(run.gate_passed(ProofGate::gate_test_suite_passes));
let verified_run = run.verify().expect("Should pass verification");
assert_eq!(verified_run.passed_gates().len(), 1);
println!("{}", verified_run.export_results());
}
#[test]
fn test_verify_requires_gate() {
let run = UnverifiedRun::new();
assert!(run.verify().is_err());
let mut run = UnverifiedRun::new();
run.mark_gate_passed(ProofGate::gate_test_suite_passes);
assert!(run.verify().is_ok());
}
}