rocket_session_store/
memory.rs1use std::{
8 collections::HashMap,
9 time::{
10 Duration,
11 Instant,
12 },
13};
14
15use rocket::tokio::sync::{
16 Mutex,
17 RwLock,
18};
19
20use crate::{
21 SessionResult,
22 Store,
23};
24
25pub struct MemoryStore<T> {
29 map: RwLock<HashMap<String, Mutex<MemoryStoreFrame<T>>>>,
30}
31
32struct MemoryStoreFrame<T> {
33 value: T,
34 expiry: Instant,
35}
36
37impl<T> Default for MemoryStore<T> {
38 fn default() -> Self {
39 Self::new()
40 }
41}
42
43impl<T> MemoryStore<T> {
44 pub fn new() -> Self {
46 Self {
47 map: RwLock::default(),
48 }
49 }
50}
51
52#[rocket::async_trait]
53impl<T> Store for MemoryStore<T>
54where
55 T: Send + Sync + Clone,
56{
57 type Value = T;
58
59 async fn get(&self, id: &str) -> SessionResult<Option<Self::Value>> {
60 let lock = self.map.read().await;
61 if let Some(frame) = lock.get(id) {
62 let frame_lock = frame.lock().await;
63 if frame_lock
64 .expiry
65 .checked_duration_since(Instant::now())
66 .is_some()
67 {
68 return Ok(Some(frame_lock.value.clone()));
69 };
70 };
71 Ok(None)
72 }
73
74 async fn set(&self, id: &str, value: Self::Value, expiry: Duration) -> SessionResult<()> {
75 let mut lock = self.map.write().await;
76 let frame = MemoryStoreFrame {
77 value,
78 expiry: Instant::now() + expiry,
79 };
80 lock.insert(id.into(), Mutex::new(frame));
81
82 Ok(())
83 }
84
85 async fn touch(&self, id: &str, duration: Duration) -> SessionResult<()> {
86 let lock = self.map.read().await;
87 if let Some(frame) = lock.get(id) {
88 let mut frame_lock = frame.lock().await;
89 frame_lock.expiry = Instant::now() + duration;
90 };
91 Ok(())
92 }
93
94 async fn remove(&self, id: &str) -> SessionResult<()> {
95 let mut lock = self.map.write().await;
96 lock.remove(id);
97
98 Ok(())
99 }
100}