zero4rs 2.0.0

zero4rs is a powerful, pragmatic, and extremely fast web framework for Rust
Documentation
use std::future::{ready, Ready};

use actix_web::dev::Payload;
use actix_web::{FromRequest, HttpRequest};

use actix_session::Session;
use actix_session::SessionExt;
use actix_session::{SessionGetError, SessionInsertError};

use crate::core::auth0::UserId;

pub struct TypedSession(pub Session);

impl FromRequest for TypedSession {
    // This is a complicated way of saying
    // "We return the same error returned by the
    // implementation of `FromRequest` for `Session`".
    type Error = <Session as FromRequest>::Error;

    // Rust does not yet support the `async` syntax in traits.
    // From request expects a `Future` as return type to allow for extractors
    // that need to perform asynchronous operations (e.g. a HTTP call)
    // We do not have a `Future`, because we don't perform any I/O,
    // so we wrap `TypedSession` into `Ready` to convert it into a `Future` that
    // resolves to the wrapped value the first time it's polled by the executor.
    type Future = Ready<Result<TypedSession, Self::Error>>;

    fn from_request(req: &HttpRequest, _payload: &mut Payload) -> Self::Future {
        ready(Ok(TypedSession(req.get_session())))
    }
}

// Session is a foreign type (defined in actix-session)
// therefore we must use the extension trait pattern:
impl TypedSession {
    const USER_ID_KEY: &'static str = "user_id";
    const USER_LOGIN_FROM_PAGE: &'static str = "login_from_page";

    pub fn renew(&self) -> &Self {
        self.0.renew();

        self
    }

    pub fn insert_user_id(&self, user_id: UserId) -> Result<(), SessionInsertError> {
        self.0.insert(Self::USER_ID_KEY, user_id)
    }

    pub fn get_user_id(&self) -> Result<Option<UserId>, SessionGetError> {
        self.0.get(Self::USER_ID_KEY)
    }

    pub fn insert_login_from_page(&self, value: &str) -> Result<(), SessionInsertError> {
        log::info!("insert_login_from_page={}", value);
        self.0.insert(Self::USER_LOGIN_FROM_PAGE, value)
    }

    pub fn get_login_from_page(&self) -> Result<Option<String>, SessionGetError> {
        self.0.get(Self::USER_LOGIN_FROM_PAGE)
    }

    pub fn log_out(self) {
        self.0.purge()
    }
}