axum_session 0.19.0

📝 Session management layer for axum that supports HTTP and Rest.
Documentation
use std::{fmt, sync::Arc};

use crate::{runner, DatabasePool, SessionService, SessionStore};
use std::sync::atomic::{AtomicBool, Ordering};
use tower_layer::Layer;

static KILL_AS_DUP: AtomicBool = AtomicBool::new(false);

/// Sessions Layer used with Axum to activate the Service.
///
/// # Examples
/// ```rust ignore
/// use axum_session::{SessionNullPool, SessionConfig, SessionStore, SessionLayer};
/// use uuid::Uuid;
///
/// let config = SessionConfig::default();
/// let session_store = SessionStore::<SessionNullPool>::new(None, config).await.unwrap();
/// let layer = SessionLayer::new(session_store);
/// ```
///
#[derive(Clone)]
pub struct SessionLayer<T>
where
    T: DatabasePool + Clone + fmt::Debug + std::marker::Sync + std::marker::Send + 'static,
{
    session_store: SessionStore<T>,
}

impl<T> SessionLayer<T>
where
    T: DatabasePool + Clone + fmt::Debug + std::marker::Sync + std::marker::Send + 'static,
{
    /// Constructs a SessionLayer used with Axum to activate the Service.
    ///
    /// # Examples
    /// ```rust ignore
    /// use axum_session::{SessionNullPool, SessionConfig, SessionStore, SessionLayer};
    /// use uuid::Uuid;
    ///
    /// let config = SessionConfig::default();
    /// let session_store = SessionStore::<SessionNullPool>::new(None, config).await.unwrap();
    /// let layer = SessionLayer::new(session_store);
    /// ```
    ///
    #[inline]
    pub fn new(session_store: SessionStore<T>) -> Self {
        SessionLayer { session_store }
    }
}

impl<S, T> Layer<S> for SessionLayer<T>
where
    T: DatabasePool + Clone + fmt::Debug + std::marker::Sync + std::marker::Send + 'static,
{
    type Service = SessionService<S, T>;

    fn layer(&self, inner: S) -> Self::Service {
        let kill_as_duplicate = KILL_AS_DUP.load(Ordering::Relaxed);

        let service = SessionService {
            session_store: self.session_store.clone(),
            handle: Arc::new(tokio::spawn(runner(
                self.session_store.clone(),
                kill_as_duplicate,
            ))),
            inner,
        };

        KILL_AS_DUP.store(true, Ordering::Relaxed);
        service
    }
}