use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct PolicyVersion {
pub hash: String,
pub loaded_at: String,
}
impl std::fmt::Display for PolicyVersion {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} (loaded {})", self.hash, self.loaded_at)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Core {
pub version: String,
pub cedar: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct VersionInfo {
pub version: String,
pub core: Core,
pub policies: PolicyVersion,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub schema: Option<PolicyVersion>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn version_info_roundtrip() {
let json = serde_json::json!({
"version": "0.1.0",
"core": {
"version": "0.3.0",
"cedar": "0.11.0"
},
"policies": {
"hash": "abc123",
"loaded_at": "2025-01-01T00:00:00Z"
}
});
let info: VersionInfo = serde_json::from_value(json.clone()).unwrap();
assert_eq!(info.version, "0.1.0");
assert_eq!(info.core.cedar, "0.11.0");
assert_eq!(info.policies.hash, "abc123");
assert!(info.schema.is_none());
let reserialized = serde_json::to_value(&info).unwrap();
assert_eq!(json, reserialized);
}
#[test]
fn version_info_with_schema() {
let json = serde_json::json!({
"version": "0.1.0",
"core": {
"version": "0.3.0",
"cedar": "0.11.0"
},
"policies": {
"hash": "abc123",
"loaded_at": "2025-01-01T00:00:00Z"
},
"schema": {
"hash": "schema123",
"loaded_at": "2025-01-01T00:00:01Z"
}
});
let info: VersionInfo = serde_json::from_value(json).unwrap();
assert_eq!(
info.schema.as_ref().map(|v| v.hash.as_str()),
Some("schema123")
);
}
}