From b0a2d8c910e943fd26825b796ae633f2e11d719f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Tue, 10 Jan 2023 10:08:44 +0100 Subject: [PATCH] Add minimal example, some formatting, bump parking_lot version --- Cargo.toml | 2 +- README.md | 30 +++++++++++++++--------------- examples/minimal/main.rs | 28 ++++++++++++++++++++++++++++ src/lib.rs | 26 ++++++++++++-------------- 4 files changed, 56 insertions(+), 30 deletions(-) create mode 100644 examples/minimal/main.rs diff --git a/Cargo.toml b/Cargo.toml index 27963f4..e984ec8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,4 +18,4 @@ categories = [ [dependencies] rand = "0.8" rocket = "0.5.0-rc.2" -parking_lot = "0.11" +parking_lot = "0.12" diff --git a/README.md b/README.md index 2c05c13..83212b5 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ The implementation is generic to support any type as session data: a custom stru The session lifetime, cookie name, and other parameters can be configured by calling chained methods on the fairing. When a session expires, the data associated with it is dropped. +Example: `Session::fairing().with_lifetime(Duration::from_secs(15))` + ## Usage To use session in a route, first make sure you have the fairing attached by calling @@ -31,7 +33,7 @@ the session list does not waste memory. ## Examples -(More examples are in the examples folder) +More examples are in the "examples" folder - run with `cargo run --example=NAME` ### Basic Example @@ -39,34 +41,32 @@ This simple example uses u64 as the session variable; note that it can be a stru it just needs to implement `Send + Sync + Default`. ```rust -#![feature(proc_macro_hygiene, decl_macro)] -#[macro_use] extern crate rocket; - -use std::time::Duration; +#[macro_use] +extern crate rocket; -// It's convenient to define a type alias: -pub type Session<'a> = rocket_session::Session<'a, u64>; +type Session<'a> = rocket_session::Session<'a, u64>; -fn main() { - rocket::ignite() +#[launch] +fn rocket() -> _ { + rocket::build() .attach(Session::fairing()) .mount("/", routes![index]) - .launch(); } #[get("/")] fn index(session: Session) -> String { let count = session.tap(|n| { - // Change the stored value (it is &mut) + // Change the stored value (it is &mut) *n += 1; - // Return something to the caller. - // This can be any type, 'tap' is generic. + // Return something to the caller. + // This can be any type, 'tap' is generic. *n }); format!("{} visits", count) } + ``` ## Extending Session by a Trait @@ -76,8 +76,8 @@ The `.tap()` method is powerful, but sometimes you may wish for something more c Here is an example of using a custom trait and the `json_dotpath` crate to implement a polymorphic store based on serde serialization. -Note that this approach is prone to data races, since every method contains its own `.tap()`. -It may be safer to simply call the `.dot_*()` methods manually in one shared closure. +Note that this approach is prone to data races if you're accessing the session object multiple times per request, +since every method contains its own `.tap()`. It may be safer to simply call the `.dot_*()` methods manually in one shared closure. ```rust use serde_json::Value; diff --git a/examples/minimal/main.rs b/examples/minimal/main.rs new file mode 100644 index 0000000..05efd1b --- /dev/null +++ b/examples/minimal/main.rs @@ -0,0 +1,28 @@ +#[macro_use] +extern crate rocket; + +use std::time::Duration; + +type Session<'a> = rocket_session::Session<'a, u64>; + +#[launch] +fn rocket() -> _ { + // This session expires in 15 seconds as a demonstration of session configuration + rocket::build() + .attach(Session::fairing().with_lifetime(Duration::from_secs(15))) + .mount("/", routes![index]) +} + +#[get("/")] +fn index(session: Session) -> String { + let count = session.tap(|n| { + // Change the stored value (it is &mut) + *n += 1; + + // Return something to the caller. + // This can be any type, 'tap' is generic. + *n + }); + + format!("{} visits", count) +} diff --git a/src/lib.rs b/src/lib.rs index 5d408a1..60c1f3e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,12 @@ +use std::borrow::Cow; +use std::collections::HashMap; +use std::fmt::{self, Display, Formatter}; +use std::marker::PhantomData; +use std::ops::Add; +use std::time::{Duration, Instant}; + use parking_lot::{Mutex, RwLock, RwLockUpgradableReadGuard}; use rand::{rngs::OsRng, Rng}; - use rocket::{ fairing::{self, Fairing, Info}, http::{Cookie, Status}, @@ -9,13 +15,6 @@ use rocket::{ Build, Request, Response, Rocket, State, }; -use std::borrow::Cow; -use std::collections::HashMap; -use std::fmt::{self, Display, Formatter}; -use std::marker::PhantomData; -use std::ops::Add; -use std::time::{Duration, Instant}; - /// Session store (shared state) #[derive(Debug)] pub struct SessionStore @@ -134,11 +133,10 @@ where let store_ug = store.inner.upgradable_read(); // Resolve session ID - let id = if let Some(cookie) = request.cookies().get(&store.config.cookie_name) { - Some(SessionID(cookie.value().to_string())) - } else { - None - }; + let id = request + .cookies() + .get(&store.config.cookie_name) + .map(|cookie| SessionID(cookie.value().to_string())); let expires = Instant::now().add(store.config.lifespan); @@ -200,7 +198,7 @@ where new_id } }), - store: store, + store, }) } }