atomr_persistence_redis/
codec.rs1use atomr_persistence::{PersistentRepr, SnapshotMetadata};
4use base64::{engine::general_purpose::STANDARD as B64, Engine as _};
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
8pub struct StoredRepr {
9 pub persistence_id: String,
10 pub sequence_nr: u64,
11 pub payload_b64: String,
12 pub manifest: String,
13 pub writer_uuid: String,
14 pub deleted: bool,
15 pub tags: Vec<String>,
16}
17
18impl From<&PersistentRepr> for StoredRepr {
19 fn from(r: &PersistentRepr) -> Self {
20 Self {
21 persistence_id: r.persistence_id.clone(),
22 sequence_nr: r.sequence_nr,
23 payload_b64: B64.encode(&r.payload),
24 manifest: r.manifest.clone(),
25 writer_uuid: r.writer_uuid.clone(),
26 deleted: r.deleted,
27 tags: r.tags.clone(),
28 }
29 }
30}
31
32impl StoredRepr {
33 pub fn into_repr(self) -> PersistentRepr {
34 PersistentRepr {
35 persistence_id: self.persistence_id,
36 sequence_nr: self.sequence_nr,
37 payload: B64.decode(self.payload_b64).unwrap_or_default(),
38 manifest: self.manifest,
39 writer_uuid: self.writer_uuid,
40 deleted: self.deleted,
41 tags: self.tags,
42 }
43 }
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize)]
47pub struct StoredSnapshot {
48 pub persistence_id: String,
49 pub sequence_nr: u64,
50 pub timestamp: u64,
51 pub payload_b64: String,
52}
53
54impl StoredSnapshot {
55 pub fn new(meta: &SnapshotMetadata, payload: &[u8]) -> Self {
56 Self {
57 persistence_id: meta.persistence_id.clone(),
58 sequence_nr: meta.sequence_nr,
59 timestamp: meta.timestamp,
60 payload_b64: B64.encode(payload),
61 }
62 }
63
64 pub fn into_parts(self) -> (SnapshotMetadata, Vec<u8>) {
65 let payload = B64.decode(self.payload_b64).unwrap_or_default();
66 (
67 SnapshotMetadata {
68 persistence_id: self.persistence_id,
69 sequence_nr: self.sequence_nr,
70 timestamp: self.timestamp,
71 },
72 payload,
73 )
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn round_trip_repr() {
83 let original = PersistentRepr {
84 persistence_id: "p1".into(),
85 sequence_nr: 7,
86 payload: vec![0, 1, 2, 255],
87 manifest: "m".into(),
88 writer_uuid: "w".into(),
89 deleted: false,
90 tags: vec!["t1".into()],
91 };
92 let stored = StoredRepr::from(&original);
93 let back = stored.into_repr();
94 assert_eq!(back.persistence_id, original.persistence_id);
95 assert_eq!(back.sequence_nr, original.sequence_nr);
96 assert_eq!(back.payload, original.payload);
97 assert_eq!(back.tags, original.tags);
98 }
99
100 #[test]
101 fn round_trip_snapshot() {
102 let meta = SnapshotMetadata { persistence_id: "p".into(), sequence_nr: 9, timestamp: 100 };
103 let payload = b"state".to_vec();
104 let stored = StoredSnapshot::new(&meta, &payload);
105 let (m, p) = stored.into_parts();
106 assert_eq!(m.sequence_nr, 9);
107 assert_eq!(p, payload);
108 }
109}