1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
6#[serde(rename_all = "lowercase")]
7pub enum MemoryTier {
8 Working,
10 Episodic,
12 Semantic,
15}
16
17impl MemoryTier {
18 #[must_use]
19 pub fn as_str(self) -> &'static str {
20 match self {
21 Self::Working => "working",
22 Self::Episodic => "episodic",
23 Self::Semantic => "semantic",
24 }
25 }
26}
27
28impl std::fmt::Display for MemoryTier {
29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 f.write_str(self.as_str())
31 }
32}
33
34impl std::str::FromStr for MemoryTier {
35 type Err = String;
36 fn from_str(s: &str) -> Result<Self, Self::Err> {
37 match s {
38 "working" => Ok(Self::Working),
39 "episodic" => Ok(Self::Episodic),
40 "semantic" => Ok(Self::Semantic),
41 other => Err(format!("unknown memory tier: {other}")),
42 }
43 }
44}
45
46#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, sqlx::Type)]
48#[sqlx(transparent)]
49pub struct ConversationId(pub i64);
50
51#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, sqlx::Type)]
53#[sqlx(transparent)]
54pub struct MessageId(pub i64);
55
56#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, sqlx::Type)]
58#[sqlx(transparent)]
59pub struct MemSceneId(pub i64);
60
61impl std::fmt::Display for MemSceneId {
62 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63 write!(f, "{}", self.0)
64 }
65}
66
67impl std::fmt::Display for ConversationId {
68 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69 write!(f, "{}", self.0)
70 }
71}
72
73impl std::fmt::Display for MessageId {
74 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75 write!(f, "{}", self.0)
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 #[test]
84 fn memory_tier_round_trip() {
85 for tier in [
86 MemoryTier::Working,
87 MemoryTier::Episodic,
88 MemoryTier::Semantic,
89 ] {
90 let s = tier.as_str();
91 let parsed: MemoryTier = s.parse().expect("should parse");
92 assert_eq!(parsed, tier);
93 assert_eq!(format!("{tier}"), s);
94 }
95 }
96
97 #[test]
98 fn memory_tier_unknown_string_errors() {
99 assert!("unknown".parse::<MemoryTier>().is_err());
100 }
101
102 #[test]
103 fn memory_tier_serde_round_trip() {
104 let json = serde_json::to_string(&MemoryTier::Semantic).unwrap();
105 assert_eq!(json, "\"semantic\"");
106 let parsed: MemoryTier = serde_json::from_str(&json).unwrap();
107 assert_eq!(parsed, MemoryTier::Semantic);
108 }
109
110 #[test]
111 fn conversation_id_display() {
112 let id = ConversationId(42);
113 assert_eq!(format!("{id}"), "42");
114 }
115
116 #[test]
117 fn message_id_display() {
118 let id = MessageId(7);
119 assert_eq!(format!("{id}"), "7");
120 }
121
122 #[test]
123 fn conversation_id_eq() {
124 assert_eq!(ConversationId(1), ConversationId(1));
125 assert_ne!(ConversationId(1), ConversationId(2));
126 }
127
128 #[test]
129 fn message_id_copy() {
130 let id = MessageId(5);
131 let copied = id;
132 assert_eq!(id, copied);
133 }
134}