use serde::{Deserialize, Serialize};
use std::time::{SystemTime, UNIX_EPOCH};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Snapshot {
pub aggregate_id: String,
pub aggregate_type: String,
pub version: i64,
pub state: serde_json::Value,
pub created_at: u64,
}
impl Snapshot {
pub fn new(
aggregate_id: impl Into<String>,
aggregate_type: impl Into<String>,
version: i64,
state: serde_json::Value,
) -> Self {
Self {
aggregate_id: aggregate_id.into(),
aggregate_type: aggregate_type.into(),
version,
state,
created_at: SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_millis() as u64,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn test_snapshot_new_stamps_created_at() {
let snap = Snapshot::new("user-1", "User", 7, json!({ "name": "Alice" }));
assert_eq!(snap.aggregate_id, "user-1");
assert_eq!(snap.aggregate_type, "User");
assert_eq!(snap.version, 7);
assert_eq!(snap.state["name"], "Alice");
assert!(snap.created_at > 0);
}
#[test]
fn test_snapshot_roundtrips_through_json() {
let snap = Snapshot::new("user-2", "User", 3, json!({ "value": 42 }));
let encoded = serde_json::to_string(&snap).unwrap();
let decoded: Snapshot = serde_json::from_str(&encoded).unwrap();
assert_eq!(snap, decoded);
}
}