pub use self::session_creator::SessionCreator;
pub use self::session_parser::{SessionParser};
pub use self::json_session_parser::{JsonSessionParser};
#[cfg(feature = "cookie")]
pub use self::cookie_session::{CookieSessionBuilder, SignedCookieSession, EncryptedCookieSession, SameSite};
mod session_creator;
mod session_parser;
mod json_session_parser;
#[cfg(feature = "cookie")]
mod cookie_session;
use crate::{Extractor, Error, http::{Request, Response}, additional::Additional};
use std::sync::Arc;
use serde::{Serialize, de::{DeserializeOwned}};
pub struct Session<B = std::collections::HashMap<String, String>, P = JsonSessionParser> {
inner: Option<B>,
phantom: std::marker::PhantomData<P>,
session_creator: Arc<Box<dyn SessionCreator>>
}
impl<B, P> Session<B, P> {
fn new(session_creator: Arc<Box<dyn SessionCreator>>) -> Session<B, P> {
Session{
inner: None,
phantom: std::marker::PhantomData,
session_creator
}
}
}
impl<B, P> std::ops::Deref for Session<B, P> {
type Target = Option<B>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<B, P> std::ops::DerefMut for Session<B, P> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl<B: Send + Serialize, P: SessionParser<B>> Session<B, P> {
pub fn apply(self, req: Response) -> Result<Response, Error> {
let content = serde_json::to_string(&self.inner)?;
self.session_creator.apply(content, req)
}
}
impl<T: Sync, B: 'static + Send + DeserializeOwned, P: 'static + Send + SessionParser<B>> Extractor<T> for Session<B, P> {
fn extract(req: &Request, additional: Arc<Additional<T>>) -> Result<Self, Error> {
if let Some(session_creator) = &additional.session_creator {
match session_creator.parse(req)? {
Some(content) => {
let inner = serde_json::from_str(&content).map_err(|e| Error::ExtractionBR(format!("{}", e)))?;
Ok(Session {
inner,
phantom: std::marker::PhantomData,
session_creator: session_creator.clone()
})
},
None => Ok(Session::new(session_creator.clone()))
}
} else {
log::error!("cataclysm error: you need to setup a `SessionCreator` before you try to use the `Session` extractor!");
Err(Error::NoSessionCreator)
}
}
}