async_session_r2d2/
lib.rs

1/*!
2*/
3
4#![forbid(unsafe_code, future_incompatible)]
5#![deny(
6    missing_debug_implementations,
7    nonstandard_style,
8    missing_docs,
9    unreachable_pub,
10    missing_copy_implementations,
11    unused_qualifications
12)]
13
14use std::sync::Arc;
15
16/// r2d2-backed session store for `async_session`
17#[derive(Debug)]
18pub struct PooledSessionStore<M: r2d2::ManageConnection> {
19    pool: Arc<r2d2::Pool<M>>,
20    table_name: String,
21}
22
23impl<M: r2d2::ManageConnection> Clone for PooledSessionStore<M> {
24    fn clone(&self) -> Self {
25        Self {
26            pool: self.pool.clone(),
27            table_name: self.table_name.clone(),
28        }
29    }
30}
31
32/// Provides generic operations for sessions across their database adapters.
33pub trait TableOperations<M: r2d2::ManageConnection> {
34    /// Adds in the necessary tables, if possible, for this session manager.
35    fn add_table(&self) -> async_session::Result<()>;
36
37    /// Cleans up expired sessions.
38    fn clean_up(&self) -> async_session::Result<()>;
39
40    /// Obtains a connection to the underlying database for this session.
41    fn connection(&self) -> async_session::Result<r2d2::PooledConnection<M>>;
42
43    /// Get the number of sessions in the store.
44    fn count(&self) -> async_session::Result<usize>;
45}
46
47impl<M: r2d2::ManageConnection> PooledSessionStore<M> {
48    /// Creates a new session manager with the provided pool and table name.
49    pub fn from_pool(pool: r2d2::Pool<M>, table_name: String) -> async_session::Result<Self>
50    where
51        Self: TableOperations<M>,
52    {
53        let session = Self {
54            pool: Arc::new(pool),
55            table_name,
56        };
57        session.add_table().and(Ok(session))
58    }
59}
60
61#[cfg(feature = "with-rusqlite")]
62pub mod sqlite;
63
64#[cfg(test)]
65mod test;