Skip to main content

laser_wire/
memory.rs

1use serde::{Deserialize, Serialize};
2
3/// A memory record as it rides the memory topic: the on-log audit of one scope's
4/// changes. This is the shape the SDK's memory facade writes and the shape a
5/// deployment folds into the versioned key-value read view, so both sides agree
6/// on the bytes without the reader importing the SDK. Ids are the text form of
7/// the SDK's memory id, kinds the snake-case kind word, so the encoding is
8/// byte-identical to the SDK's own record. Runtime-free and portable, like the
9/// rest of the wire contract.
10#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
11pub enum MemoryRecord {
12    /// A remembered item: its id, kind word, and body.
13    Item {
14        id: String,
15        kind: String,
16        body: Vec<u8>,
17    },
18    /// A tombstone removing an item from recall.
19    Forget { target: String },
20    /// A feedback signal reweighting an item's recall rank.
21    Feedback { target: String, weight: f32 },
22}
23
24#[cfg(test)]
25mod tests {
26    use super::*;
27    use crate::framing::{decode_named, encode_named};
28
29    #[test]
30    fn given_each_variant_when_round_tripped_then_should_preserve_fields() {
31        for record in [
32            MemoryRecord::Item {
33                id: "01KWM3K3XEP3NP5TN850J17YBP".to_owned(),
34                kind: "fact".to_owned(),
35                body: b"checkout is slow".to_vec(),
36            },
37            MemoryRecord::Forget {
38                target: "01KWM3K3XEP3NP5TN850J17YBP".to_owned(),
39            },
40            MemoryRecord::Feedback {
41                target: "01KWM3K3XEP3NP5TN850J17YBP".to_owned(),
42                weight: 1.5,
43            },
44        ] {
45            let bytes = encode_named(&record).expect("encodes");
46            let back: MemoryRecord = decode_named(&bytes).expect("decodes");
47            assert_eq!(back, record);
48        }
49    }
50}