use crate::status::StateStatus;
use ledvar_core::Node;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DiffNode {
pub node: Node,
pub identity_key: String,
pub content_hash: String,
pub state_status: StateStatus,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DiffResult {
#[allow(missing_docs)]
pub protocol_version: String,
#[allow(missing_docs)]
pub origin_id: String,
#[allow(missing_docs)]
pub provider_name: String,
#[allow(missing_docs)]
pub timestamp: i64,
#[allow(missing_docs)]
pub fingerprint: Option<String>,
#[allow(missing_docs)]
pub parent_origin_id: Option<String>,
#[allow(missing_docs)]
pub labels: BTreeMap<String, String>,
pub nodes: Vec<DiffNode>,
}
impl DiffResult {
pub fn has_drift(&self) -> bool {
self.nodes.iter().any(|n| n.state_status.is_drift())
}
}
#[cfg(test)]
mod tests {
use super::*;
use ledvar_core::Node;
#[test]
fn wire_vocabulary_is_stable() {
let result = DiffResult {
protocol_version: "0.1.0".to_string(),
origin_id: "o".to_string(),
provider_name: "p".to_string(),
timestamp: 1,
fingerprint: None,
parent_origin_id: None,
labels: BTreeMap::new(),
nodes: vec![DiffNode {
node: Node {
path: vec!["a".into()],
content: Default::default(),
labels: Default::default(),
refs: Vec::new(),
},
identity_key: "i".to_string(),
content_hash: "c".to_string(),
state_status: StateStatus::Added,
}],
};
let v = serde_json::to_value(&result).unwrap();
assert_eq!(v["protocol_version"], "0.1.0");
assert_eq!(v["nodes"][0]["state_status"], "Added");
assert_eq!(v["nodes"][0]["identity_key"], "i");
assert_eq!(v["nodes"][0]["content_hash"], "c");
assert_eq!(v["nodes"][0]["node"]["path"][0], "a");
let back: DiffResult = serde_json::from_value(v).unwrap();
assert_eq!(back, result, "the wire form round-trips losslessly");
}
}