Skip to main content

disyn_memory/
in_memory.rs

1use async_trait::async_trait;
2use std::sync::Mutex;
3
4use disyn_core::Result;
5use disyn_core::ports::MemoryStore;
6use disyn_core::types::{ExecutionReport, Facts, MemoryContext};
7
8pub struct InMemoryStore {
9    episodes: Mutex<Vec<ExecutionReport>>,
10}
11
12impl InMemoryStore {
13    pub fn new() -> Self {
14        Self {
15            episodes: Mutex::new(Vec::new()),
16        }
17    }
18}
19
20impl Default for InMemoryStore {
21    fn default() -> Self {
22        Self::new()
23    }
24}
25
26#[async_trait]
27impl MemoryStore for InMemoryStore {
28    async fn retrieve(&self, _facts: &Facts) -> Result<MemoryContext> {
29        Ok(MemoryContext {
30            relevant_episodes: vec![],
31            summary: None,
32            weighted_passages: vec![],
33        })
34    }
35
36    async fn persist(&self, report: &ExecutionReport) -> Result<()> {
37        self.episodes
38            .lock()
39            .map_err(|e| disyn_core::Error::Memory(e.to_string()))?
40            .push(report.clone());
41        Ok(())
42    }
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48
49    #[tokio::test]
50    async fn retrieve_returns_empty_context_initially() {
51        let store = InMemoryStore::new();
52        let facts = Facts {
53            entities: vec!["test".into()],
54            relations: vec![],
55            confidence: 1.0,
56        };
57        let ctx = store.retrieve(&facts).await.unwrap();
58        assert!(ctx.relevant_episodes.is_empty());
59        assert!(ctx.summary.is_none());
60    }
61}