1use crate::AppError;
2use crate::extractor::from_request::FromRequest;
3use crate::handler::{FnOnceTuple, Req, TypedHandler, handler_to_svc};
4use crate::http::response::into_response::IntoResponse;
5use crate::router::HttpSvc;
6use bytes::Bytes;
7use http_body::Body;
8use http_body_util::BodyExt;
9use hyper::Response;
10use miko_core::{BoxError, MikoError};
11use std::future::Future;
12use std::sync::Arc;
13use tower::{Layer, Service, ServiceExt, util::BoxCloneService};
14
15pub trait LayerExt<Svc>: Sized {
42 fn layer<L, B>(self, layer: L) -> HttpSvc<Req>
44 where
45 Svc: Service<Req>,
46 L: Layer<Svc>,
47 L::Service: Service<Req, Response = Response<B>> + Clone + Send + 'static,
48 <L::Service as Service<Req>>::Error: Into<AppError>,
49 B: Body<Data = Bytes> + Send + Sync + 'static,
50 B::Error: Into<BoxError>,
51 <L::Service as Service<Req>>::Future: Send + 'static;
52
53 fn with_layer<L, B>(self, layer: L) -> HttpSvc<Req>
55 where
56 Svc: Service<Req>,
57 L: Layer<Svc>,
58 L::Service: Service<Req, Response = Response<B>> + Clone + Send + 'static,
59 <L::Service as Service<Req>>::Error: Into<AppError>,
60 B: Body<Data = Bytes> + Send + Sync + 'static,
61 B::Error: Into<BoxError>,
62 <L::Service as Service<Req>>::Future: Send + 'static,
63 {
64 self.layer(layer)
65 }
66}
67
68pub trait WithState<S>: Sized {
70 fn with_state<A, Fut, R, M>(self, state: S) -> HttpSvc<Req>
71 where
72 Self: FnOnceTuple<A, Output = Fut> + Clone + Send + Sync + 'static,
73 A: FromRequest<S, M> + Send + 'static,
74 Fut: Future<Output = R> + Send + 'static,
75 R: IntoResponse,
76 M: Send + Sync + 'static;
77}
78
79impl LayerExt<HttpSvc<Req>> for HttpSvc<Req> {
80 fn layer<L, B>(self, layer: L) -> HttpSvc<Req>
81 where
82 L: Layer<Self>,
83 L::Service: Service<Req, Response = Response<B>> + Clone + Send + 'static,
84 <L::Service as Service<Req>>::Error: Into<AppError>,
85 B: Body<Data = Bytes> + Send + Sync + 'static,
86 B::Error: Into<BoxError>,
87 <L::Service as Service<Req>>::Future: Send + 'static,
88 {
89 let layered_svc = layer
90 .layer(self)
91 .map_response(|resp| {
92 let (parts, body) = resp.into_parts();
93 let body = body.map_err(|e| MikoError::from(e.into())).boxed_unsync();
94 Response::from_parts(parts, body)
95 })
96 .map_err(Into::into);
97 BoxCloneService::new(layered_svc)
98 }
99}
100
101impl<F, S> WithState<S> for F
102where
103 S: Send + Sync + 'static,
104{
105 fn with_state<A, Fut, R, M>(self, state: S) -> HttpSvc<Req>
106 where
107 F: FnOnceTuple<A, Output = Fut> + Clone + Send + Sync + 'static,
108 A: FromRequest<S, M> + Send + 'static,
109 Fut: Future<Output = R> + Send + 'static,
110 R: IntoResponse,
111 M: Send + Sync + 'static,
112 {
113 let handler_arc = Arc::new(TypedHandler::new(self, Arc::new(state)));
114 handler_to_svc(handler_arc)
115 }
116}