author_web/session/store/
in_memory.rs

1use crate::session::store::{SessionDataValueStorage, SessionStore};
2use crate::session::SessionKey;
3use async_trait::async_trait;
4use parking_lot::Mutex;
5use std::borrow::Borrow;
6use std::collections::HashMap;
7use std::hash::Hash;
8use std::sync::Arc;
9use uuid::Uuid;
10
11pub struct InMemorySessionStore<S = InMemorySessionData<String, String>, K = Uuid> {
12    sessions: Mutex<HashMap<K, Arc<S>>>,
13}
14
15impl<S, K> InMemorySessionStore<S, K> {
16    pub fn new() -> Self {
17        InMemorySessionStore {
18            sessions: Mutex::new(HashMap::new()),
19        }
20    }
21}
22
23#[async_trait]
24impl<S, K> SessionStore for InMemorySessionStore<S, K>
25where
26    S: CreateNew,
27    K: SessionKey + Clone + Eq + Hash + Send + Sync,
28{
29    type Session = Arc<S>;
30    type Key = K;
31
32    async fn create_session(&self) -> anyhow::Result<(Self::Key, Self::Session)> {
33        let key = K::generate();
34        let session = Arc::new(S::new());
35
36        self.sessions.lock().insert(key.clone(), session.clone());
37
38        Ok((key, session))
39    }
40
41    async fn load_session(&self, key: &K) -> anyhow::Result<Option<Self::Session>> {
42        Ok(self.sessions.lock().get(key).cloned())
43    }
44}
45
46pub trait CreateNew: Send + Sync {
47    fn new() -> Self;
48}
49
50impl<S> CreateNew for Arc<S>
51where
52    S: CreateNew,
53{
54    fn new() -> Self {
55        Arc::new(S::new())
56    }
57}
58
59pub type InMemorySession<K = String, V = String> = Arc<InMemorySessionData<K, V>>;
60
61pub struct InMemorySessionData<K = String, V = String> {
62    values: Mutex<HashMap<K, V>>,
63}
64
65impl<K, V> InMemorySessionData<K, V> {
66    pub fn new() -> Self {
67        InMemorySessionData {
68            values: Mutex::new(HashMap::new()),
69        }
70    }
71}
72
73impl<K, V> CreateNew for InMemorySessionData<K, V>
74where
75    K: Send + Sync,
76    V: Send + Sync,
77{
78    fn new() -> Self {
79        InMemorySessionData::new()
80    }
81}
82
83impl SessionKey for Uuid {
84    fn generate() -> Self {
85        Uuid::new_v4()
86    }
87}
88
89#[async_trait]
90impl<K, V> SessionDataValueStorage<K, V> for InMemorySessionData<K, V>
91where
92    K: Clone + Hash + Eq + Send,
93    V: Clone + Send,
94{
95    async fn set_value<KVal, VVal>(&self, key: KVal, val: VVal) -> anyhow::Result<()>
96    where
97        KVal: Into<K> + Send,
98        VVal: Into<V> + Send,
99    {
100        self.values.lock().insert(key.into(), val.into());
101        Ok(())
102    }
103
104    async fn unset_value<KVal>(&self, key: KVal) -> anyhow::Result<()>
105    where
106        KVal: Into<K> + Send,
107    {
108        self.values.lock().remove(&key.into());
109        Ok(())
110    }
111
112    async fn get_value<KRef>(&self, key: &KRef) -> anyhow::Result<Option<V>>
113    where
114        KRef: Hash + Eq + ?Sized + Sync,
115        K: Borrow<KRef>,
116    {
117        Ok(self.values.lock().get(key).cloned())
118    }
119}