actix_state_guards/
middleware.rs1use crate::Guard as GuardTrait;
2
3use std::marker::PhantomData;
4use std::rc::Rc;
5use std::{future::Future, pin::Pin};
6
7use actix_web::body::MessageBody;
8use actix_web::dev::{forward_ready, Service as ServiceTrait, ServiceRequest, ServiceResponse};
9use actix_web::{Error as ActixWebError, FromRequest, ResponseError};
10
11pub struct StateGuardMiddleware<Service, Guard, Args, Error> {
12 service: Rc<Service>,
13 guard: Rc<Guard>,
14 args_marker: PhantomData<Args>,
15 error_marker: PhantomData<Error>,
16}
17
18impl<Service, Guard, Args, Error> StateGuardMiddleware<Service, Guard, Args, Error> {
19 pub(crate) fn new(
20 guard: Rc<Guard>,
21 service: Service,
22 ) -> StateGuardMiddleware<Service, Guard, Args, Error> {
23 Self {
24 guard,
25 service: Rc::new(service),
26 args_marker: PhantomData,
27 error_marker: PhantomData,
28 }
29 }
30}
31
32impl<Service, Body, Guard, Args, Error> ServiceTrait<ServiceRequest>
33 for StateGuardMiddleware<Service, Guard, Args, Error>
34where
35 Service: ServiceTrait<ServiceRequest, Response = ServiceResponse<Body>, Error = ActixWebError>
36 + 'static,
37 Body: MessageBody,
38 Guard: GuardTrait<Args, Error>,
39 Error: ResponseError + 'static,
40 Args: FromRequest,
41{
42 type Response = Service::Response;
43
44 type Error = Service::Error;
45
46 type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
47
48 forward_ready!(service);
49
50 fn call(&self, mut req: ServiceRequest) -> Self::Future {
51 let service = Rc::clone(&self.service);
52 let guard = Rc::clone(&self.guard);
53
54 Box::pin(async move {
55 match guard.call_guard_with_service_request(&mut req).await {
56 Ok(()) => service.call(req).await,
57 Err(err) => Err(err.into()),
58 }
59 })
60 }
61}