use session crate

This commit is contained in:
2019-12-31 02:58:53 +01:00
parent fdbc7947f6
commit 21b83758c8
4 changed files with 63 additions and 42 deletions
+7 -4
View File
@@ -12,9 +12,11 @@ use serde_json::Value;
use rocket_contrib::serve::StaticFiles;
use rocket_contrib::templates::Template;
mod session;
//mod session;
mod store;
use rocket_session::Session;
use crate::store::form::{
collect_card_form, render_card_fields, render_empty_fields, MapFromForm, RenderedCard,
RenderedField,
@@ -22,11 +24,12 @@ use crate::store::form::{
use crate::store::Store;
use parking_lot::RwLock;
use crate::session::{Session, SessionID, SessionStore};
//use crate::session::Session;
use rocket::request::Form;
use rocket::response::Redirect;
use rocket::{Request, State};
use rocket::State;
use std::env;
use std::time::Duration;
#[derive(Serialize, Debug)]
pub struct ListContext<'a> {
@@ -187,7 +190,7 @@ fn main() {
rocket::ignite()
.attach(Template::fairing())
.attach(Session::fairing())
.attach(Session::fairing(Duration::from_secs(3600)))
.manage(RwLock::new(store))
.mount("/", StaticFiles::from(cwd.join("templates/static/")))
.mount(
+39 -38
View File
@@ -1,19 +1,20 @@
use json_dotpath::DotPaths;
use parking_lot::{Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard};
use parking_lot::RwLock;
use rand::Rng;
use rocket::fairing::{self, Fairing, Info};
use rocket::request::FromRequest;
use rocket::response::ResponseBuilder;
use rocket::{
http::{Cookie, Cookies, Status},
Data, Outcome, Request, Response, Rocket, State,
http::{Cookie, Status},
Outcome, Request, Response, Rocket, State,
};
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use serde::Serialize;
use serde_json::{Map, Value};
use std::borrow::Cow;
use std::collections::HashMap;
use std::ops::{Deref, DerefMut};
use std::time::{Instant, Duration};
use std::ops::Add;
const SESSION_ID: &'static str = "SESSID";
@@ -22,12 +23,13 @@ type SessionsMap = HashMap<String, SessionInstance>;
#[derive(Debug)]
struct SessionInstance {
data: serde_json::Map<String, Value>,
// TODO expiration
expires: Instant,
}
#[derive(Default, Debug)]
pub struct SessionStore {
inner: RwLock<SessionsMap>,
lifespan: Duration,
}
#[derive(PartialEq, Hash, Clone, Debug)]
@@ -88,15 +90,34 @@ impl<'a> Session<'a> {
SessionFairing
}
pub fn get<T: DeserializeOwned>(&self, path: &str) -> Option<T> {
let rg = self.store.inner.read();
if let Some(ses) = rg.get(&self.id.0) {
ses.data.dot_get(path)
fn tap<T>(&self, func : impl FnOnce(&mut serde_json::Map<String, Value>) -> T) -> T {
let mut wg = self.store.inner.write();
if let Some(instance) = wg.get_mut(&self.id.0) {
instance.expires = Instant::now().add(self.store.lifespan);
func(&mut instance.data)
} else {
None
let mut data = Map::new();
let rv = func(&mut data);
wg.insert(self.id.0.clone(), SessionInstance {
data: data,
expires: Instant::now().add(self.store.lifespan),
});
rv
}
}
pub fn renew(&self) {
self.tap(|_| ())
}
pub fn reset(&self) {
self.tap(|data| data.clear())
}
pub fn get<T: DeserializeOwned>(&self, path: &str) -> Option<T> {
self.tap(|data| data.dot_get(path))
}
pub fn get_or<T: DeserializeOwned>(&self, path: &str, def: T) -> T {
self.get(path).unwrap_or(def)
}
@@ -110,39 +131,19 @@ impl<'a> Session<'a> {
}
pub fn take<T: DeserializeOwned>(&self, path: &str) -> Option<T> {
let mut wg = self.store.inner.write();
if let Some(ses) = wg.get_mut(&self.id.0) {
ses.data.dot_take(path)
} else {
None
}
self.tap(|data| data.dot_take(path))
}
pub fn replace<O: DeserializeOwned, N: Serialize>(&self, path: &str, new: N) -> Option<O> {
let mut wg = self.store.inner.write();
if let Some(ses) = wg.get_mut(&self.id.0) {
ses.data.dot_replace(path, new)
} else {
None
}
self.tap(|data| data.dot_replace(path, new))
}
pub fn set<T: Serialize>(&self, path: &str, value: T) {
let mut wg = self.store.inner.write();
if let Some(ses) = wg.get_mut(&self.id.0) {
ses.data.dot_set(path, value);
} else {
let mut map = Map::new();
map.dot_set(path, value);
wg.insert(self.id.0.clone(), SessionInstance { data: map });
}
self.tap(|data| data.dot_set(path, value));
}
pub fn remove(&self, path: &str) {
let mut wg = self.store.inner.write();
if let Some(ses) = wg.get_mut(&self.id.0) {
ses.data.dot_remove(path);
}
pub fn remove(&self, path: &str) -> bool {
self.tap(|data| data.dot_remove(path))
}
}