use serde::Serialize;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum CutoverVerdict {
Pass,
OldStillSpeaks,
Unproven,
}
impl CutoverVerdict {
pub fn to_judgement(self) -> crate::report::Judgement {
use crate::report::Judgement;
match self {
CutoverVerdict::OldStillSpeaks => Judgement::Established,
CutoverVerdict::Pass => Judgement::NotEstablished {
reason: "the retired family is silent while the new plane carries traffic".into(),
},
CutoverVerdict::Unproven => Judgement::Unobservable {
reason: "both planes were silent — a dead fleet passes the silence half \
for free (RFC 05 §3.1)"
.into(),
},
}
}
}
impl From<crate::report::Judgement> for CutoverVerdict {
fn from(j: crate::report::Judgement) -> CutoverVerdict {
use crate::report::Judgement;
match j {
Judgement::Established => CutoverVerdict::OldStillSpeaks,
Judgement::NotEstablished { .. } => CutoverVerdict::Pass,
Judgement::NotAsked | Judgement::Unobservable { .. } => CutoverVerdict::Unproven,
}
}
}
#[derive(Debug, Clone, Serialize)]
pub struct CutoverReport {
pub old_root: String,
pub new_prefix: String,
pub window_s: f64,
pub old_samples: u64,
pub old_keys_seen: usize,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub old_examples: Vec<String>,
pub new_samples: u64,
pub leak_samples: u64,
pub leaked_keys_seen: usize,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub leak_examples: Vec<String>,
pub dropped: u64,
pub verdict: CutoverVerdict,
}