|  |  | @ -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  |  |  |  | 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. |  |  |  | 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 |  |  |  | ## Usage | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | To use session in a route, first make sure you have the fairing attached by calling |  |  |  | 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 |  |  |  | ## Examples | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | (More examples are in the examples folder) |  |  |  | More examples are in the "examples" folder - run with `cargo run --example=NAME` | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | ### Basic Example |  |  |  | ### 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`.  |  |  |  | it just needs to implement `Send + Sync + Default`.  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | ```rust |  |  |  | ```rust | 
			
		
	
		
		
			
				
					
					|  |  |  | #![feature(proc_macro_hygiene, decl_macro)] |  |  |  | #[macro_use] | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | #[macro_use] extern crate rocket; |  |  |  | extern crate rocket; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | use std::time::Duration; |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | // It's convenient to define a type alias: |  |  |  | type Session<'a> = rocket_session::Session<'a, u64>; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | pub type Session<'a> = rocket_session::Session<'a, u64>; |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | fn main() { |  |  |  | #[launch] | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     rocket::ignite() |  |  |  | fn rocket() -> _ { | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     rocket::build() | 
			
		
	
		
		
			
				
					
					|  |  |  |         .attach(Session::fairing()) |  |  |  |         .attach(Session::fairing()) | 
			
		
	
		
		
			
				
					
					|  |  |  |         .mount("/", routes![index]) |  |  |  |         .mount("/", routes![index]) | 
			
		
	
		
		
			
				
					
					|  |  |  |         .launch(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | #[get("/")] |  |  |  | #[get("/")] | 
			
		
	
		
		
			
				
					
					|  |  |  | fn index(session: Session) -> String { |  |  |  | fn index(session: Session) -> String { | 
			
		
	
		
		
			
				
					
					|  |  |  |     let count = session.tap(|n| { |  |  |  |     let count = session.tap(|n| { | 
			
		
	
		
		
			
				
					
					|  |  |  |         // Change the stored value (it is &mut)  |  |  |  |         // Change the stored value (it is &mut) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         *n += 1; |  |  |  |         *n += 1; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         // Return something to the caller.  |  |  |  |         // Return something to the caller. | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         // This can be any type, 'tap' is generic.         |  |  |  |         // This can be any type, 'tap' is generic. | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         *n |  |  |  |         *n | 
			
		
	
		
		
			
				
					
					|  |  |  |     }); |  |  |  |     }); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     format!("{} visits", count) |  |  |  |     format!("{} visits", count) | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | ``` |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | ## Extending Session by a Trait |  |  |  | ## 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 |  |  |  | Here is an example of using a custom trait and the `json_dotpath` crate to implement | 
			
		
	
		
		
			
				
					
					|  |  |  | a polymorphic store based on serde serialization.  |  |  |  | a polymorphic store based on serde serialization.  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | Note that this approach is prone to data races, since every method contains its own `.tap()`. |  |  |  | Note that this approach is prone to data races if you're accessing the session object multiple times per request,  | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | It may be safer to simply call the `.dot_*()` methods manually in one shared closure. |  |  |  | since every method contains its own `.tap()`. It may be safer to simply call the `.dot_*()` methods manually in one shared closure. | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | ```rust |  |  |  | ```rust | 
			
		
	
		
		
			
				
					
					|  |  |  | use serde_json::Value; |  |  |  | use serde_json::Value; | 
			
		
	
	
		
		
			
				
					|  |  | 
 |