threatflux_cache/
storage.rs1use crate::entry::CacheEntry;
4use crate::error::Result;
5use async_trait::async_trait;
6use serde::{Serialize, de::DeserializeOwned};
7use std::collections::HashMap;
8use std::hash::Hash;
9
10pub type EntryMap<K, V, M> = HashMap<K, Vec<CacheEntry<K, V, M>>>;
12
13#[async_trait]
15pub trait StorageBackend: Send + Sync + 'static {
16 type Key: Serialize + DeserializeOwned + Hash + Eq + Clone + Send + Sync;
18 type Value: Serialize + DeserializeOwned + Clone + Send + Sync;
20 type Metadata: Serialize + DeserializeOwned + Clone + Send + Sync;
22
23 async fn save(&self, entries: &EntryMap<Self::Key, Self::Value, Self::Metadata>) -> Result<()>;
25
26 async fn load(&self) -> Result<EntryMap<Self::Key, Self::Value, Self::Metadata>>;
28
29 async fn remove(&self, key: &Self::Key) -> Result<()>;
31
32 async fn clear(&self) -> Result<()>;
34
35 async fn contains(&self, key: &Self::Key) -> Result<bool> {
37 let entries = self.load().await?;
38 Ok(entries.contains_key(key))
39 }
40
41 async fn size_bytes(&self) -> Result<u64>;
43
44 async fn compact(&self) -> Result<()> {
46 Ok(()) }
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53 #[tokio::test]
54 async fn test_default_storage_methods() {
55 use crate::test_utils::TestBackend;
56 use std::collections::HashMap;
57
58 let backend = TestBackend::default();
59 let mut map = HashMap::new();
60 map.insert(
61 "a".to_string(),
62 vec![CacheEntry::new("a".to_string(), "v".to_string())],
63 );
64 backend.save(&map).await.unwrap();
65
66 assert!(backend.contains(&"a".to_string()).await.unwrap());
67 assert!(!backend.contains(&"b".to_string()).await.unwrap());
68 assert!(backend.size_bytes().await.unwrap() > 0);
69 backend.compact().await.unwrap();
70 }
71}