Skip to main content

walrus_daemon/feature/
memory.rs

1//! Memory backend enum for static dispatch over memory implementations.
2//!
3//! Wraps [`InMemory`] and [`SqliteMemory<NoEmbedder>`] with Memory trait
4//! delegation, following the Provider enum pattern.
5
6use anyhow::Result;
7use memory::{InMemory, Memory, MemoryEntry, NoEmbedder, RecallOptions, SqliteMemory};
8use std::future::Future;
9
10/// Memory backend selected from configuration.
11///
12/// Delegates all [`Memory`] trait methods to the inner variant.
13pub enum MemoryBackend {
14    /// Volatile in-memory store.
15    InMemory(InMemory),
16    /// SQLite-backed persistent store (no embedder).
17    Sqlite(SqliteMemory<NoEmbedder>),
18}
19
20impl MemoryBackend {
21    /// Create an in-memory backend.
22    pub fn in_memory() -> Self {
23        Self::InMemory(InMemory::new())
24    }
25
26    /// Create a SQLite backend at the given path.
27    pub fn sqlite(path: &str) -> Result<Self> {
28        Ok(Self::Sqlite(SqliteMemory::open(path)?))
29    }
30}
31
32impl Memory for MemoryBackend {
33    fn get(&self, key: &str) -> Option<String> {
34        match self {
35            Self::InMemory(m) => m.get(key),
36            Self::Sqlite(m) => m.get(key),
37        }
38    }
39
40    fn entries(&self) -> Vec<(String, String)> {
41        match self {
42            Self::InMemory(m) => m.entries(),
43            Self::Sqlite(m) => m.entries(),
44        }
45    }
46
47    fn set(&self, key: impl Into<String>, value: impl Into<String>) -> Option<String> {
48        match self {
49            Self::InMemory(m) => m.set(key, value),
50            Self::Sqlite(m) => m.set(key, value),
51        }
52    }
53
54    fn remove(&self, key: &str) -> Option<String> {
55        match self {
56            Self::InMemory(m) => m.remove(key),
57            Self::Sqlite(m) => m.remove(key),
58        }
59    }
60
61    fn store(
62        &self,
63        key: impl Into<String> + Send,
64        value: impl Into<String> + Send,
65    ) -> impl Future<Output = Result<()>> + Send {
66        let key = key.into();
67        let value = value.into();
68        async move {
69            match self {
70                Self::InMemory(m) => m.store(key, value).await,
71                Self::Sqlite(m) => m.store(key, value).await,
72            }
73        }
74    }
75
76    fn recall(
77        &self,
78        query: &str,
79        options: RecallOptions,
80    ) -> impl Future<Output = Result<Vec<MemoryEntry>>> + Send {
81        let query = query.to_owned();
82        async move {
83            match self {
84                Self::InMemory(m) => m.recall(&query, options).await,
85                Self::Sqlite(m) => m.recall(&query, options).await,
86            }
87        }
88    }
89
90    fn compile_relevant(&self, query: &str) -> impl Future<Output = String> + Send {
91        let query = query.to_owned();
92        async move {
93            match self {
94                Self::InMemory(m) => m.compile_relevant(&query).await,
95                Self::Sqlite(m) => m.compile_relevant(&query).await,
96            }
97        }
98    }
99}