Skip to main content

awc/middleware/
mod.rs

1mod redirect;
2
3use std::marker::PhantomData;
4
5use actix_service::Service;
6
7pub use self::redirect::Redirect;
8
9/// Trait for transform a type to another one.
10/// Both the input and output type should impl [actix_service::Service] trait.
11pub trait Transform<S, Req> {
12    type Transform: Service<Req>;
13
14    /// Creates and returns a new Transform component.
15    fn new_transform(self, service: S) -> Self::Transform;
16}
17
18#[doc(hidden)]
19/// Helper struct for constructing Nested types that would call `Transform::new_transform`
20/// in a chain.
21///
22/// The child field would be called first and the output `Service` type is
23/// passed to parent as input type.
24pub struct NestTransform<T1, T2, S, Req>
25where
26    T1: Transform<S, Req>,
27    T2: Transform<T1::Transform, Req>,
28{
29    child: T1,
30    parent: T2,
31    _service: PhantomData<(S, Req)>,
32}
33
34impl<T1, T2, S, Req> NestTransform<T1, T2, S, Req>
35where
36    T1: Transform<S, Req>,
37    T2: Transform<T1::Transform, Req>,
38{
39    pub(crate) fn new(child: T1, parent: T2) -> Self {
40        NestTransform {
41            child,
42            parent,
43            _service: PhantomData,
44        }
45    }
46}
47
48impl<T1, T2, S, Req> Transform<S, Req> for NestTransform<T1, T2, S, Req>
49where
50    T1: Transform<S, Req>,
51    T2: Transform<T1::Transform, Req>,
52{
53    type Transform = T2::Transform;
54
55    fn new_transform(self, service: S) -> Self::Transform {
56        let service = self.child.new_transform(service);
57        self.parent.new_transform(service)
58    }
59}
60
61/// Dummy impl for kick start `NestTransform` type in `ClientBuilder` type
62impl<S, Req> Transform<S, Req> for ()
63where
64    S: Service<Req>,
65{
66    type Transform = S;
67
68    fn new_transform(self, service: S) -> Self::Transform {
69        service
70    }
71}