1use crate::ArcRouteLayer;
2use bytes::Bytes;
3use http::{Request, Response};
4use satex_core::body::Body;
5use satex_core::component::Args;
6use satex_core::make::Make;
7use satex_core::util::try_downcast;
8use satex_core::{BoxError, Error};
9use satex_service::RouteService;
10use std::sync::Arc;
11use tower::{Layer, Service};
12
13pub trait MakeRouteLayer: Make {
14 type Layer: Layer<RouteService>;
15
16 fn make(&self, args: Args) -> Result<Self::Layer, Error>;
17}
18
19#[derive(Clone)]
20pub struct ArcMakeRouteLayer(Arc<dyn MakeRouteLayer<Layer=ArcRouteLayer> + Send + Sync>);
21
22impl ArcMakeRouteLayer {
23 pub fn new<M, L, S, E, ResBody>(make: M) -> Self
24 where
25 M: MakeRouteLayer<Layer=L> + Send + Sync + 'static,
26 L: Layer<RouteService, Service=S> + Send + Sync + 'static,
27 S: Service<Request<Body>, Response=Response<ResBody>, Error=E>
28 + Clone
29 + Send
30 + Sync
31 + 'static,
32 E: Into<BoxError>,
33 ResBody: http_body::Body<Data = Bytes> + Send + 'static,
34 ResBody::Error: Into<BoxError>,
35 {
36 try_downcast::<ArcMakeRouteLayer, _>(make)
37 .unwrap_or_else(|make| Self(Arc::new(MapMake(make))))
38 }
39}
40
41struct MapMake<M>(M);
42
43impl<M, L, S, E, ResBody> Make for MapMake<M>
44where
45 M: MakeRouteLayer<Layer=L>,
46 S: Service<Request<Body>, Response=Response<ResBody>, Error=E>,
47 L: Layer<RouteService, Service=S>,
48{
49 fn name(&self) -> &'static str {
50 self.0.name()
51 }
52}
53
54impl<M, L, S, E, ResBody> MakeRouteLayer for MapMake<M>
55where
56 M: MakeRouteLayer<Layer=L>,
57 L: Layer<RouteService, Service=S> + Send + Sync + 'static,
58 S: Service<Request<Body>, Response=Response<ResBody>, Error=E>
59 + Clone
60 + Send
61 + Sync
62 + 'static,
63 E: Into<BoxError>,
64 ResBody: http_body::Body<Data = Bytes> + Send + 'static,
65 ResBody::Error: Into<BoxError>,
66{
67 type Layer = ArcRouteLayer;
68
69 fn make(&self, args: Args) -> Result<Self::Layer, Error> {
70 self.0.make(args).map(ArcRouteLayer::new)
71 }
72}
73
74impl Make for ArcMakeRouteLayer {
75 fn name(&self) -> &'static str {
76 self.0.name()
77 }
78}
79
80impl MakeRouteLayer for ArcMakeRouteLayer {
81 type Layer = ArcRouteLayer;
82
83 fn make(&self, args: Args) -> Result<Self::Layer, Error> {
84 self.0.make(args)
85 }
86}