gotham/middleware/state.rs
1//! State driven middleware to enable attachment of values to request state.
2//!
3//! This module provides generics to enable attaching (appropriate) values to
4//! the state of a request, through the use of `Middleware`. Middleware can
5//! be created via `StateMiddleware::with`, with the provided value being the
6//! value to attach to the request state.
7use crate::handler::HandlerFuture;
8use crate::middleware::{Middleware, NewMiddleware};
9use crate::state::{State, StateData};
10use std::panic::RefUnwindSafe;
11use std::pin::Pin;
12
13/// Middleware binding for generic types to enable easy shared state.
14///
15/// This acts as nothing more than a `Middleware` instance which will
16/// attach a generic type to a request `State`, however it removes a
17/// barrier for users to Gotham who might not know the internals.
18///
19/// The generic types inside this struct can (and will) be cloned
20/// often, so wrap your expensive types in reference counts as needed.
21#[derive(Clone)]
22pub struct StateMiddleware<T>
23where
24 T: Clone + RefUnwindSafe + StateData + Sync,
25{
26 t: T,
27}
28
29/// Main implementation.
30impl<T> StateMiddleware<T>
31where
32 T: Clone + RefUnwindSafe + StateData + Sync,
33{
34 /// Creates a new middleware binding, taking ownership of the state data.
35 pub fn new(t: T) -> Self {
36 Self { t }
37 }
38}
39
40/// `Middleware` trait implementation.
41impl<T> Middleware for StateMiddleware<T>
42where
43 T: Clone + RefUnwindSafe + StateData + Sync,
44{
45 /// Attaches the inner generic value to the request state.
46 ///
47 /// This will enable the `Handler` to borrow the value directly from the state.
48 fn call<Chain>(self, mut state: State, chain: Chain) -> Pin<Box<HandlerFuture>>
49 where
50 Chain: FnOnce(State) -> Pin<Box<HandlerFuture>>,
51 {
52 state.put(self.t);
53 chain(state)
54 }
55}
56
57/// `NewMiddleware` trait implementation.
58impl<T> NewMiddleware for StateMiddleware<T>
59where
60 T: Clone + RefUnwindSafe + StateData + Sync,
61{
62 type Instance = Self;
63
64 /// Clones the current middleware to a new instance.
65 fn new_middleware(&self) -> anyhow::Result<Self::Instance> {
66 Ok(self.clone())
67 }
68}