use super::asked::Asked;
use serde::Serialize;
#[derive(Debug, Clone, Serialize)]
pub struct ProducerDiff {
pub producer: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub served_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub local_version: Option<String>,
pub findings: Vec<String>,
}
#[derive(Debug, Clone, Serialize)]
pub struct RegistryDiff {
pub producers: Vec<ProducerDiff>,
#[serde(skip_serializing_if = "Asked::is_not_asked", default)]
pub collapsed: Asked<Vec<CollapsedProducer>>,
}
impl RegistryDiff {
pub fn disagreeing(&self) -> usize {
self.producers
.iter()
.filter(|p| !p.findings.is_empty())
.count()
}
pub fn self_disagreeing(&self) -> usize {
self.collapsed
.as_deref()
.map(|c| c.iter().filter(|c| !c.agreed).count())
.unwrap_or(0)
}
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize)]
pub struct SliceDisagreement {
pub producer: String,
pub bus_version: String,
pub dirs_version: String,
pub shape_differs: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct CollapsedProducer {
pub producer: String,
pub origins: Vec<String>,
pub versions: Vec<String>,
pub agreed: bool,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_collapse_receipt_keeps_not_asked_off_the_wire() {
let asked = RegistryDiff {
producers: vec![],
collapsed: Asked::Asked(vec![CollapsedProducer {
producer: "sysinfo".into(),
origins: vec!["h-3fa9c2d41b7e".into(), "h-8b1e07af22c9".into()],
versions: vec!["1.1".into(), "1.0".into()],
agreed: false,
}]),
};
assert_eq!(
serde_json::to_value(&asked).expect("serialize"),
serde_json::json!({
"producers": [],
"collapsed": [{
"producer": "sysinfo",
"origins": ["h-3fa9c2d41b7e", "h-8b1e07af22c9"],
"versions": ["1.1", "1.0"],
"agreed": false,
}],
})
);
assert_eq!(asked.self_disagreeing(), 1);
let asked_clean = RegistryDiff {
producers: vec![],
collapsed: Asked::Asked(vec![]),
};
assert_eq!(
serde_json::to_value(&asked_clean).expect("serialize"),
serde_json::json!({"producers": [], "collapsed": []}),
"asked and nothing collapsed is a present, empty list"
);
let not_asked = RegistryDiff {
producers: vec![],
collapsed: Asked::NotAsked,
};
assert_eq!(
serde_json::to_value(¬_asked).expect("serialize"),
serde_json::json!({"producers": []}),
"not asked is absence — never `[]`, never `null`"
);
assert_eq!(
not_asked.self_disagreeing(),
0,
"and its zero is a different zero, which the renderer says out loud"
);
}
}