service_layer_rs/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//! Service Layer
//!

//! # Example
//!
//! ```rust
//! use service_layer_rs::util::FnService;
//! use service_layer_rs::{Layer, Service, ServiceBuilder};
//! use std::convert::Infallible;
//!
//! pub struct LogService<S> {
//!     inner: S,
//!     name: String,
//! }
//!
//! impl<S, Request> Service<Request> for LogService<S>
//! where
//!     S: Service<Request>,
//!     Request: Send + 'static,
//! {
//!     type Response = S::Response;
//!     type Error = S::Error;
//!
//!     async fn call(
//!         &self,
//!         request: Request,
//!     ) -> Result<Self::Response, Self::Error> {
//!         println!("LogService<{}> start", self.name);
//!         let res = self.inner.call(request).await;
//!         println!("LogService<{}> end", self.name);
//!         res
//!     }
//! }
//!
//! pub struct LogLayer(pub String);
//!
//! impl<S> Layer<S> for LogLayer
//! where
//!     S: Send + Sync + 'static
//! {
//!     type Service = LogService<S>;
//!
//!     fn layer(self, inner: S) -> Self::Service {
//!         LogService { inner, name: self.0 }
//!     }
//! }
//!
//! async fn main() {
//!     let svc = FnService::new(|req: String| async move {
//!         println!("handle: {}", req);
//!         Ok::<_, Infallible>(req)
//!     });
//!
//!     let svc = ServiceBuilder::service(svc)
//!         .layer(LogLayer("Test".to_string()))
//!         .build();
//!
//!     let ss = svc.boxed();
//!     let res: Result<String, Infallible> = ss.call("hello".to_owned()).await;
//!     println!("{:?}", res);
//! }
//! ```

pub mod service;
pub mod util;

pub use service::{BoxService, Service};

/// Decorates a Service
pub trait Layer<S> {
    /// The wrapped service
    type Service;
    /// Wrap the given service with the middleware, returning a new service that has been decorated with the middleware.
    fn layer(self, inner: S) -> Self::Service;
}

/// Builder types to compose layers and services
pub struct ServiceBuilder<S> {
    inner: S,
}

impl<S> ServiceBuilder<S> {
    pub fn service<Request>(inner: S) -> Self
    where
        S: Service<Request>,
    {
        ServiceBuilder { inner }
    }

    pub fn layer<L, T, Request>(self, l: L) -> ServiceBuilder<T>
    where
        S: Service<Request>,
        T: Service<Request>,
        L: Layer<S, Service=T>,
    {
        let inner = l.layer(self.inner);
        ServiceBuilder { inner }
    }

    pub fn build<Request>(self) -> S
    where
        S: Service<Request>,
    {
        self.inner
    }

    pub async fn call<Request>(self, request: Request) -> Result<S::Response, S::Error>
    where
        S: Service<Request>,
    {
        self.inner.call(request).await
    }
}