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
}
}