Skip to main content

doido_storage/providers/
memory.rs

1//! In-memory [`Service`] — stores object bytes in a `HashMap`, the storage
2//! analogue of `doido_cache::MemoryStore`.
3//!
4//! It keeps nothing on disk and is wiped when the process exits, so it's ideal
5//! for tests and quick local development. Like disk, it has no native access URL
6//! and is served through the app's signed [`crate::serving`] routes.
7
8use crate::error::StorageError;
9use crate::service::Service;
10use doido_core::Result;
11use std::collections::HashMap;
12use std::sync::Mutex;
13
14/// A [`Service`] that keeps every object in memory.
15pub struct MemoryService {
16    name: String,
17    data: Mutex<HashMap<String, Vec<u8>>>,
18}
19
20impl MemoryService {
21    /// Create an empty in-memory service named `name`.
22    pub fn new(name: impl Into<String>) -> Self {
23        Self {
24            name: name.into(),
25            data: Mutex::new(HashMap::new()),
26        }
27    }
28}
29
30impl Default for MemoryService {
31    fn default() -> Self {
32        Self::new("memory")
33    }
34}
35
36#[async_trait::async_trait]
37impl Service for MemoryService {
38    fn name(&self) -> &str {
39        &self.name
40    }
41
42    async fn upload(&self, key: &str, data: Vec<u8>, _content_type: Option<&str>) -> Result<()> {
43        self.data.lock().unwrap().insert(key.to_string(), data);
44        Ok(())
45    }
46
47    async fn download(&self, key: &str) -> Result<Vec<u8>> {
48        self.data
49            .lock()
50            .unwrap()
51            .get(key)
52            .cloned()
53            .ok_or_else(|| StorageError::NotFound(key.to_string()).into())
54    }
55
56    async fn delete(&self, key: &str) -> Result<()> {
57        self.data.lock().unwrap().remove(key);
58        Ok(())
59    }
60
61    async fn exists(&self, key: &str) -> Result<bool> {
62        Ok(self.data.lock().unwrap().contains_key(key))
63    }
64
65    async fn size(&self, key: &str) -> Result<u64> {
66        self.data
67            .lock()
68            .unwrap()
69            .get(key)
70            .map(|b| b.len() as u64)
71            .ok_or_else(|| StorageError::NotFound(key.to_string()).into())
72    }
73}