|
| 1 | +use actix_session::{Session, SessionExt, SessionGetError, SessionInsertError}; |
| 2 | +use actix_web::dev::Payload; |
| 3 | +use actix_web::{FromRequest, HttpRequest}; |
| 4 | +use std::future::{ready, Ready}; |
| 5 | +use uuid::Uuid; |
| 6 | +pub struct TypedSession(Session); |
| 7 | + |
| 8 | +impl TypedSession { |
| 9 | + const USER_ID_KEY: &'static str = "user_id"; |
| 10 | + |
| 11 | + pub fn renew(&self) { |
| 12 | + self.0.renew(); |
| 13 | + } |
| 14 | + |
| 15 | + pub fn insert_user_id(&self, user_id: Uuid) -> Result<(), SessionInsertError> { |
| 16 | + self.0.insert(Self::USER_ID_KEY, user_id) |
| 17 | + } |
| 18 | + |
| 19 | + pub fn get_user_id(&self) -> Result<Option<Uuid>, SessionGetError> { |
| 20 | + self.0.get(Self::USER_ID_KEY) |
| 21 | + } |
| 22 | +} |
| 23 | + |
| 24 | +impl FromRequest for TypedSession { |
| 25 | + // This is a complicated way of saying |
| 26 | + // "We return the same error returned by the |
| 27 | + // implementation of `FromRequest` for `Session`". |
| 28 | + type Error = <Session as FromRequest>::Error; |
| 29 | + // Rust does not yet support the `async` syntax in traits. |
| 30 | + // From request expects a `Future` as return type to allow for extractors |
| 31 | + // that need to perform asynchronous operations (e.g. a HTTP call) |
| 32 | + // We do not have a `Future`, because we don't perform any I/O, |
| 33 | + // so we wrap `TypedSession` into `Ready` to convert it into a `Future` that |
| 34 | + // resolves to the wrapped value the first time it's polled by the executor. |
| 35 | + type Future = Ready<Result<TypedSession, Self::Error>>; |
| 36 | + |
| 37 | + // The `from_request` method is called by actix-web to convert the incoming request into a `TypedSession`. |
| 38 | + fn from_request(req: &HttpRequest, _payload: &mut Payload) -> Self::Future { |
| 39 | + ready(Ok(TypedSession(req.get_session()))) |
| 40 | + } |
| 41 | +} |
0 commit comments