actix_state_guards/
guard.rs

1use crate::GuardError;
2
3use std::future::Future;
4use std::pin::Pin;
5
6use actix_web::dev::ServiceRequest;
7use actix_web::{FromRequest, Handler, ResponseError};
8
9pub trait Guard<Args: FromRequest, Error: ResponseError>:
10    Handler<Args, Output = Result<(), Error>>
11{
12    fn call_guard_with_service_request<'a, 'b: 'a>(
13        &'a self,
14        req: &'b mut ServiceRequest,
15    ) -> Pin<Box<dyn Future<Output = Result<(), GuardError<Error>>> + 'a>> {
16        let (mut_req, mut payload) = req.parts_mut();
17
18        // waiting for async functions in traits <https://github.com/rust-lang/rust/issues/91611>
19        Box::pin(async move {
20            match Args::from_request(&mut_req, &mut payload).await {
21                Ok(args) => self
22                    .call(args)
23                    .await
24                    .map_err(|err| GuardError::GuardCall(err)),
25                Err(err) => Err(GuardError::FromRequest(err.into())),
26            }
27        })
28    }
29}
30
31impl<T, Args, Error> Guard<Args, Error> for T
32where
33    T: Handler<Args, Output = Result<(), Error>>,
34    Args: FromRequest,
35    Error: ResponseError,
36{
37}