1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
8#[serde(rename_all = "lowercase")]
9#[non_exhaustive]
10pub enum MemoryTier {
11 Working,
13 Episodic,
15 Semantic,
18 Persona,
21}
22
23impl MemoryTier {
24 #[must_use]
35 pub fn as_str(self) -> &'static str {
36 match self {
37 Self::Working => "working",
38 Self::Episodic => "episodic",
39 Self::Semantic => "semantic",
40 Self::Persona => "persona",
41 }
42 }
43}
44
45impl std::fmt::Display for MemoryTier {
46 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47 f.write_str(self.as_str())
48 }
49}
50
51impl std::str::FromStr for MemoryTier {
52 type Err = String;
53 fn from_str(s: &str) -> Result<Self, Self::Err> {
54 match s {
55 "working" => Ok(Self::Working),
56 "episodic" => Ok(Self::Episodic),
57 "semantic" => Ok(Self::Semantic),
58 "persona" => Ok(Self::Persona),
59 other => Err(format!("unknown memory tier: {other}")),
60 }
61 }
62}
63
64#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, sqlx::Type)]
78#[sqlx(transparent)]
79pub struct ConversationId(pub i64);
80
81impl std::fmt::Display for ConversationId {
82 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83 write!(f, "{}", self.0)
84 }
85}
86
87#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, sqlx::Type)]
101#[sqlx(transparent)]
102pub struct MessageId(pub i64);
103
104#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, sqlx::Type)]
118#[sqlx(transparent)]
119pub struct MemSceneId(pub i64);
120
121impl std::fmt::Display for MemSceneId {
122 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
123 write!(f, "{}", self.0)
124 }
125}
126
127impl std::fmt::Display for MessageId {
128 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
129 write!(f, "{}", self.0)
130 }
131}
132
133#[derive(
147 Debug,
148 Clone,
149 Copy,
150 PartialEq,
151 Eq,
152 PartialOrd,
153 Ord,
154 Hash,
155 sqlx::Type,
156 serde::Serialize,
157 serde::Deserialize,
158)]
159#[sqlx(transparent)]
160pub struct ExperienceId(pub i64);
161
162impl std::fmt::Display for ExperienceId {
163 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
164 write!(f, "{}", self.0)
165 }
166}
167
168#[derive(
182 Debug,
183 Clone,
184 Copy,
185 PartialEq,
186 Eq,
187 PartialOrd,
188 Ord,
189 Hash,
190 sqlx::Type,
191 serde::Serialize,
192 serde::Deserialize,
193)]
194#[sqlx(transparent)]
195pub struct EntityId(pub i64);
196
197impl std::fmt::Display for EntityId {
198 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
199 write!(f, "{}", self.0)
200 }
201}
202
203#[cfg(test)]
204mod tests {
205 use super::*;
206
207 #[test]
208 fn memory_tier_round_trip() {
209 for tier in [
210 MemoryTier::Working,
211 MemoryTier::Episodic,
212 MemoryTier::Semantic,
213 MemoryTier::Persona,
214 ] {
215 let s = tier.as_str();
216 let parsed: MemoryTier = s.parse().expect("should parse");
217 assert_eq!(parsed, tier);
218 assert_eq!(format!("{tier}"), s);
219 }
220 }
221
222 #[test]
223 fn memory_tier_unknown_string_errors() {
224 assert!("unknown".parse::<MemoryTier>().is_err());
225 }
226
227 #[test]
228 fn memory_tier_serde_round_trip() {
229 let json = serde_json::to_string(&MemoryTier::Semantic).unwrap();
230 assert_eq!(json, "\"semantic\"");
231 let parsed: MemoryTier = serde_json::from_str(&json).unwrap();
232 assert_eq!(parsed, MemoryTier::Semantic);
233 }
234
235 #[test]
236 fn conversation_id_display() {
237 let id = ConversationId(42);
238 assert_eq!(format!("{id}"), "42");
239 }
240
241 #[test]
242 fn message_id_display() {
243 let id = MessageId(7);
244 assert_eq!(format!("{id}"), "7");
245 }
246
247 #[test]
248 fn conversation_id_eq() {
249 assert_eq!(ConversationId(1), ConversationId(1));
250 assert_ne!(ConversationId(1), ConversationId(2));
251 }
252
253 #[test]
254 fn message_id_copy() {
255 let id = MessageId(5);
256 let copied = id;
257 assert_eq!(id, copied);
258 }
259
260 #[test]
261 fn experience_id_display() {
262 let id = ExperienceId(10);
263 assert_eq!(format!("{id}"), "10");
264 }
265
266 #[test]
267 fn entity_id_display() {
268 let id = EntityId(5);
269 assert_eq!(format!("{id}"), "5");
270 }
271
272 #[test]
273 fn experience_id_ord() {
274 assert!(ExperienceId(1) < ExperienceId(2));
275 assert_eq!(ExperienceId(3), ExperienceId(3));
276 }
277
278 #[test]
279 fn entity_id_hash() {
280 use std::collections::HashSet;
281 let mut set = HashSet::new();
282 set.insert(EntityId(1));
283 set.insert(EntityId(2));
284 set.insert(EntityId(1));
285 assert_eq!(set.len(), 2);
286 }
287}