use session crate
This commit is contained in:
Generated
+15
@@ -829,6 +829,7 @@ dependencies = [
|
||||
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rocket 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rocket_contrib 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rocket_session 0.1.0 (git+https://git.ondrovo.com/packages/rocket_session.git)",
|
||||
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -878,6 +879,19 @@ dependencies = [
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rocket_session"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.ondrovo.com/packages/rocket_session.git#2aaa877cb5121fcd19ac5e6f4817af9c8878d64b"
|
||||
dependencies = [
|
||||
"json_dotpath 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rocket 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.16"
|
||||
@@ -1372,6 +1386,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum rocket_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "79aa1366f9b2eccddc05971e17c5de7bb75a5431eb12c2b5c66545fd348647f4"
|
||||
"checksum rocket_contrib 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e0fa5c1392135adc0f96a02ba150ac4c765e27c58dbfd32aa40678e948f6e56f"
|
||||
"checksum rocket_http 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b1391457ee4e80b40d4b57fa5765c0f2836b20d73bcbee4e3f35d93cf3b80817"
|
||||
"checksum rocket_session 0.1.0 (git+https://git.ondrovo.com/packages/rocket_session.git)" = "<none>"
|
||||
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
|
||||
"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
|
||||
"checksum safemem 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
|
||||
|
||||
@@ -16,6 +16,8 @@ json_dotpath = "0.1.2"
|
||||
titlecase = "0.10.0"
|
||||
rand = "0.7.2"
|
||||
|
||||
rocket_session = { git = "https://git.ondrovo.com/packages/rocket_session.git" }
|
||||
|
||||
# special data structure that preserves order
|
||||
indexmap = { version="1.3.0", features=["serde-1"] }
|
||||
|
||||
|
||||
+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