shared/infrastructure/cache/in_memory/
adapter.rs1use async_trait::async_trait;
2use std::collections::HashMap;
3use std::sync::Arc;
4use std::time::{Duration, Instant};
5use tokio::sync::Mutex;
6
7use crate::domain::cache::CacheAdapter;
8use crate::error::{CoreError, InternalError, Result};
9
10struct CacheEntry {
11 value: String,
12 expires_at: Option<Instant>,
13}
14
15pub struct InMemoryAdapter {
16 store: Arc<Mutex<HashMap<String, CacheEntry>>>,
17}
18
19impl InMemoryAdapter {
20 pub fn new() -> Self {
21 Self {
22 store: Arc::new(Mutex::new(HashMap::new())),
23 }
24 }
25}
26
27impl Default for InMemoryAdapter {
28 fn default() -> Self {
29 Self::new()
30 }
31}
32
33#[async_trait]
34impl CacheAdapter for InMemoryAdapter {
35 async fn insert(&self, key: &str, value: &str, expiration: u64) -> Result<()> {
36 let mut store = self.store.lock().await;
37 store.insert(
38 key.to_string(),
39 CacheEntry {
40 value: value.to_string(),
41 expires_at: Some(Instant::now() + Duration::from_secs(expiration)),
42 },
43 );
44 Ok(())
45 }
46
47 async fn find_one(&self, key: &str) -> Result<Option<String>> {
48 let store = self.store.lock().await;
49
50 match store.get(key) {
51 Some(entry) => {
52 if let Some(expires_at) = entry.expires_at
53 && Instant::now() > expires_at
54 {
55 return Ok(None);
56 }
57 Ok(Some(entry.value.clone()))
58 }
59 None => Ok(None),
60 }
61 }
62
63 async fn update(&self, key: &str, value: &str, expiration: u64) -> Result<()> {
64 let mut store = self.store.lock().await;
65 store.entry(key.to_string()).and_modify(|v| {
66 *v = CacheEntry {
67 value: value.to_string(),
68 expires_at: Some(Instant::now() + Duration::from_secs(expiration)),
69 };
70 });
71
72 Ok(())
73 }
74
75 async fn increment(&self, key: &str) -> Result<u64> {
76 let mut store = self.store.lock().await;
77 let entry = store.entry(key.to_string()).or_insert(CacheEntry {
78 value: "0".to_string(),
79 expires_at: None,
80 });
81
82 let new_val: u64 = entry.value.parse().unwrap_or(0) + 1;
83 entry.value = new_val.to_string();
84
85 Ok(new_val)
86 }
87
88 async fn delete_one(&self, key: &str) -> Result<()> {
89 let mut store = self.store.lock().await;
90 if store.remove(key).is_none() {
91 return Err(CoreError::Internal(InternalError::Cache(
92 "Failed deleting an entry form cache".to_string(),
93 )));
94 }
95
96 Ok(())
97 }
98
99 async fn flush_all(&self) -> Result<()> {
100 let mut store = self.store.lock().await;
101 store.clear();
102
103 Ok(())
104 }
105}