use session crate
This commit is contained in:
+7
-4
@@ -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
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user