1#![allow(clippy::needless_return)]
2#![allow(clippy::borrowed_box)]
3
4use serde::{Deserialize, Serialize};
5use thruster::{
6 context::typed_hyper_context::TypedHyperContext, middleware_fn, ContextState, MiddlewareNext,
7 MiddlewareResult,
8};
9
10pub mod session_stores;
11use session_stores::SessionStore;
12
13#[derive(Clone)]
14pub struct Session<S> {
15 pub cookie_name: String,
16 pub data: Option<S>,
17}
18
19#[middleware_fn]
20pub async fn session_middleware<
21 C: Send + ContextState<Session<S>> + ContextState<Box<T>>,
22 T: 'static + SessionStore<S> + Sync,
23 S: 'static + Send + Sync + for<'a> Deserialize<'a> + Serialize + Clone,
24>(
25 mut context: TypedHyperContext<C>,
26 next: MiddlewareNext<TypedHyperContext<C>>,
27) -> MiddlewareResult<TypedHyperContext<C>> {
28 let session_store: &Box<_> = context.extra.get();
29 let current_session: &Session<_> = context.extra.get();
30
31 let cookie_value = context.cookies.get(¤t_session.cookie_name);
32 if let Some(cookie_value) = cookie_value {
33 let session = session_store.retrieve(&cookie_value.value).await;
34
35 *context.extra.get_mut() = Session {
36 data: session,
37 ..current_session.clone()
38 };
39 } else {
40 return next(context).await;
41 }
42
43 return next(context).await;
44}