pub use self::session_creator::SessionCreator;
pub use self::cookie_session::{CookieSession, SameSite};
mod session_creator;
mod cookie_session;
use crate::{Extractor, Error, http::{Request, Response}, additional::Additional};
use std::collections::HashMap;
use std::sync::Arc;
pub struct Session {
values: HashMap<String, String>,
changed: bool,
session_creator: Arc<Box<dyn SessionCreator>>
}
impl Session {
fn new<A: 'static + SessionCreator>(session_creator: A) -> Session {
let session_creator: Arc<Box<dyn SessionCreator>> = Arc::new(Box::new(session_creator));
Session{
values: HashMap::new(),
changed: false,
session_creator
}
}
pub fn new_with_values<A: 'static + SessionCreator>(session_creator: A, values: HashMap<String, String>) -> Session {
let mut session = Session::new(session_creator);
session.values = values;
session
}
}
impl Session {
pub fn set<A: Into<String>, B: Into<String>>(&mut self, key: A, value: B) {
self.changed = true;
self.values.insert(key.into(), value.into());
}
pub fn get<T: AsRef<str>>(&self, key: T) -> Option<&String> {
self.values.get(key.as_ref())
}
pub fn clear(&mut self) {
self.changed = true;
self.values.clear();
}
pub fn apply(self, req: Response) -> Response {
if self.changed {
self.session_creator.apply(&self.values, req)
} else {
req
}
}
}
impl<T: Sync> Extractor<T> for Session {
fn extract(req: &Request, additional: Arc<Additional<T>>) -> Result<Self, Error> {
if let Some(session_creator) = &additional.session_creator {
session_creator.create(req)
} else {
log::error!("cataclysm error: you need to setup a `SessionCreator` before you try to use the `Session` extractor!");
Err(Error::NoSessionCreator)
}
}
}