Skip to main content

walrus_memory/mem/
mod.rs

1//! In-memory implementation of the Memory trait.
2
3use std::sync::{Arc, Mutex};
4use wcore::Memory;
5
6/// In-memory store backed by `Arc<Mutex<Vec<(String, String)>>>`.
7///
8/// `Clone` is cheap — clones share the same underlying storage.
9#[derive(Default, Debug, Clone)]
10pub struct InMemory {
11    entries: Arc<Mutex<Vec<(String, String)>>>,
12}
13
14impl InMemory {
15    /// Create an empty store.
16    pub fn new() -> Self {
17        Self::default()
18    }
19
20    /// Create a store pre-populated with entries.
21    pub fn with_entries(entries: impl IntoIterator<Item = (String, String)>) -> Self {
22        Self {
23            entries: Arc::new(Mutex::new(entries.into_iter().collect())),
24        }
25    }
26}
27
28impl Memory for InMemory {
29    fn get(&self, key: &str) -> Option<String> {
30        let entries = self.entries.lock().unwrap_or_else(|e| e.into_inner());
31        entries
32            .iter()
33            .find(|(k, _)| k == key)
34            .map(|(_, v)| v.clone())
35    }
36
37    fn entries(&self) -> Vec<(String, String)> {
38        self.entries
39            .lock()
40            .unwrap_or_else(|e| e.into_inner())
41            .clone()
42    }
43
44    fn set(&self, key: impl Into<String>, value: impl Into<String>) -> Option<String> {
45        let key = key.into();
46        let value = value.into();
47        let mut entries = self.entries.lock().unwrap_or_else(|e| e.into_inner());
48        if let Some(existing) = entries.iter_mut().find(|(k, _)| *k == key) {
49            Some(std::mem::replace(&mut existing.1, value))
50        } else {
51            entries.push((key, value));
52            None
53        }
54    }
55
56    fn remove(&self, key: &str) -> Option<String> {
57        let mut entries = self.entries.lock().unwrap_or_else(|e| e.into_inner());
58        let idx = entries.iter().position(|(k, _)| k == key)?;
59        Some(entries.remove(idx).1)
60    }
61}