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
use std::future::Future;
/// # Example
///
/// ```rust
/// use service_layer_rs::{FnService, Layer, Service, ServiceBuilder};
///
/// struct LogMiddle<S> {
/// svc: S,
/// name: String,
/// }
///
/// impl<S, Request, Response> Service<Request, Response> for LogMiddle<S>
/// where
/// S: Service<Request, Response>,
/// {
/// async fn call(&self, req: Request) -> Response {
/// println!("start {} --->", self.name);
/// let resp = self.svc.call(req).await;
/// println!("end {} <---", self.name);
/// resp
/// }
/// }
///
/// struct LogMiddleLayer {
/// log: String,
/// }
///
/// impl<S> Layer<S, LogMiddle<S>> for LogMiddleLayer {
/// fn layer(self, svc: S) -> LogMiddle<S> {
/// LogMiddle { svc, name: self.log }
/// }
/// }
///
/// let svc = FnService::new(|req: String| async move {
/// format!("hello {}", req);
/// });
/// let svc = ServiceBuilder::new(svc)
/// .layer(LogMiddleLayer { log: "test".into() })
/// .build();
/// svc.call("1".to_string()).await;
/// ```
// #[trait_variant::make(Send)]
#[allow(async_fn_in_trait)]
pub trait Service<Request, Response> {
async fn call(&self, request: Request) -> Response;
}
pub trait Layer<S, T> {
fn layer(self, svc: S) -> T;
}
pub struct ServiceBuilder<S> {
inner: S,
}
impl<S> ServiceBuilder<S> {
pub fn new<Request, Response>(inner: S) -> Self
where
S: Service<Request, Response>,
{
ServiceBuilder { inner }
}
pub fn layer<Request, Response, L, T>(self, l: L) -> ServiceBuilder<T>
where
S: Service<Request, Response>,
T: Service<Request, Response>,
L: Layer<S, T>,
{
let inner = l.layer(self.inner);
ServiceBuilder { inner }
}
pub fn build<Request, Response>(self) -> S
where
S: Service<Request, Response>,
{
self.inner
}
#[allow(dead_code)]
async fn call<Request, Response>(self, request: Request) -> Response
where
S: Service<Request, Response>,
{
self.inner.call(request).await
}
}
pub struct FnService<F>(F);
impl<F> FnService<F> {
pub fn new(f: F) -> Self {
FnService(f)
}
}
impl<Request, Response, F, Fut> Service<Request, Response> for FnService<F>
where
F: Fn(Request) -> Fut,
Fut: Future<Output = Response>,
{
async fn call(&self, req: Request) -> Response {
self.0(req).await
}
}