1 use std::{convert::Infallible, fmt}; 2 3 use http::Request; 4 use tower::Service; 5 6 use crate::{ 7 body::HttpBody, 8 handler::Handler, 9 routing::{future::RouteFuture, Route}, 10 Router, 11 }; 12 13 pub(crate) struct BoxedIntoRoute<S, B, E>(Box<dyn ErasedIntoRoute<S, B, E>>); 14 15 impl<S, B> BoxedIntoRoute<S, B, Infallible> 16 where 17 S: Clone + Send + Sync + 'static, 18 B: Send + 'static, 19 { from_handler<H, T>(handler: H) -> Self where H: Handler<T, S, B>, T: 'static, B: HttpBody,20 pub(crate) fn from_handler<H, T>(handler: H) -> Self 21 where 22 H: Handler<T, S, B>, 23 T: 'static, 24 B: HttpBody, 25 { 26 Self(Box::new(MakeErasedHandler { 27 handler, 28 into_route: |handler, state| Route::new(Handler::with_state(handler, state)), 29 })) 30 } 31 } 32 33 impl<S, B, E> BoxedIntoRoute<S, B, E> { map<F, B2, E2>(self, f: F) -> BoxedIntoRoute<S, B2, E2> where S: 'static, B: 'static, E: 'static, F: FnOnce(Route<B, E>) -> Route<B2, E2> + Clone + Send + 'static, B2: HttpBody + 'static, E2: 'static,34 pub(crate) fn map<F, B2, E2>(self, f: F) -> BoxedIntoRoute<S, B2, E2> 35 where 36 S: 'static, 37 B: 'static, 38 E: 'static, 39 F: FnOnce(Route<B, E>) -> Route<B2, E2> + Clone + Send + 'static, 40 B2: HttpBody + 'static, 41 E2: 'static, 42 { 43 BoxedIntoRoute(Box::new(Map { 44 inner: self.0, 45 layer: Box::new(f), 46 })) 47 } 48 into_route(self, state: S) -> Route<B, E>49 pub(crate) fn into_route(self, state: S) -> Route<B, E> { 50 self.0.into_route(state) 51 } 52 } 53 54 impl<S, B, E> Clone for BoxedIntoRoute<S, B, E> { clone(&self) -> Self55 fn clone(&self) -> Self { 56 Self(self.0.clone_box()) 57 } 58 } 59 60 impl<S, B, E> fmt::Debug for BoxedIntoRoute<S, B, E> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result61 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 62 f.debug_tuple("BoxedIntoRoute").finish() 63 } 64 } 65 66 pub(crate) trait ErasedIntoRoute<S, B, E>: Send { clone_box(&self) -> Box<dyn ErasedIntoRoute<S, B, E>>67 fn clone_box(&self) -> Box<dyn ErasedIntoRoute<S, B, E>>; 68 into_route(self: Box<Self>, state: S) -> Route<B, E>69 fn into_route(self: Box<Self>, state: S) -> Route<B, E>; 70 call_with_state(self: Box<Self>, request: Request<B>, state: S) -> RouteFuture<B, E>71 fn call_with_state(self: Box<Self>, request: Request<B>, state: S) -> RouteFuture<B, E>; 72 } 73 74 pub(crate) struct MakeErasedHandler<H, S, B> { 75 pub(crate) handler: H, 76 pub(crate) into_route: fn(H, S) -> Route<B>, 77 } 78 79 impl<H, S, B> ErasedIntoRoute<S, B, Infallible> for MakeErasedHandler<H, S, B> 80 where 81 H: Clone + Send + 'static, 82 S: 'static, 83 B: HttpBody + 'static, 84 { clone_box(&self) -> Box<dyn ErasedIntoRoute<S, B, Infallible>>85 fn clone_box(&self) -> Box<dyn ErasedIntoRoute<S, B, Infallible>> { 86 Box::new(self.clone()) 87 } 88 into_route(self: Box<Self>, state: S) -> Route<B>89 fn into_route(self: Box<Self>, state: S) -> Route<B> { 90 (self.into_route)(self.handler, state) 91 } 92 call_with_state( self: Box<Self>, request: Request<B>, state: S, ) -> RouteFuture<B, Infallible>93 fn call_with_state( 94 self: Box<Self>, 95 request: Request<B>, 96 state: S, 97 ) -> RouteFuture<B, Infallible> { 98 self.into_route(state).call(request) 99 } 100 } 101 102 impl<H, S, B> Clone for MakeErasedHandler<H, S, B> 103 where 104 H: Clone, 105 { clone(&self) -> Self106 fn clone(&self) -> Self { 107 Self { 108 handler: self.handler.clone(), 109 into_route: self.into_route, 110 } 111 } 112 } 113 114 pub(crate) struct MakeErasedRouter<S, B> { 115 pub(crate) router: Router<S, B>, 116 pub(crate) into_route: fn(Router<S, B>, S) -> Route<B>, 117 } 118 119 impl<S, B> ErasedIntoRoute<S, B, Infallible> for MakeErasedRouter<S, B> 120 where 121 S: Clone + Send + Sync + 'static, 122 B: HttpBody + Send + 'static, 123 { clone_box(&self) -> Box<dyn ErasedIntoRoute<S, B, Infallible>>124 fn clone_box(&self) -> Box<dyn ErasedIntoRoute<S, B, Infallible>> { 125 Box::new(self.clone()) 126 } 127 into_route(self: Box<Self>, state: S) -> Route<B>128 fn into_route(self: Box<Self>, state: S) -> Route<B> { 129 (self.into_route)(self.router, state) 130 } 131 call_with_state( mut self: Box<Self>, request: Request<B>, state: S, ) -> RouteFuture<B, Infallible>132 fn call_with_state( 133 mut self: Box<Self>, 134 request: Request<B>, 135 state: S, 136 ) -> RouteFuture<B, Infallible> { 137 self.router.call_with_state(request, state) 138 } 139 } 140 141 impl<S, B> Clone for MakeErasedRouter<S, B> 142 where 143 S: Clone, 144 { clone(&self) -> Self145 fn clone(&self) -> Self { 146 Self { 147 router: self.router.clone(), 148 into_route: self.into_route, 149 } 150 } 151 } 152 153 pub(crate) struct Map<S, B, E, B2, E2> { 154 pub(crate) inner: Box<dyn ErasedIntoRoute<S, B, E>>, 155 pub(crate) layer: Box<dyn LayerFn<B, E, B2, E2>>, 156 } 157 158 impl<S, B, E, B2, E2> ErasedIntoRoute<S, B2, E2> for Map<S, B, E, B2, E2> 159 where 160 S: 'static, 161 B: 'static, 162 E: 'static, 163 B2: HttpBody + 'static, 164 E2: 'static, 165 { clone_box(&self) -> Box<dyn ErasedIntoRoute<S, B2, E2>>166 fn clone_box(&self) -> Box<dyn ErasedIntoRoute<S, B2, E2>> { 167 Box::new(Self { 168 inner: self.inner.clone_box(), 169 layer: self.layer.clone_box(), 170 }) 171 } 172 into_route(self: Box<Self>, state: S) -> Route<B2, E2>173 fn into_route(self: Box<Self>, state: S) -> Route<B2, E2> { 174 (self.layer)(self.inner.into_route(state)) 175 } 176 call_with_state(self: Box<Self>, request: Request<B2>, state: S) -> RouteFuture<B2, E2>177 fn call_with_state(self: Box<Self>, request: Request<B2>, state: S) -> RouteFuture<B2, E2> { 178 (self.layer)(self.inner.into_route(state)).call(request) 179 } 180 } 181 182 pub(crate) trait LayerFn<B, E, B2, E2>: FnOnce(Route<B, E>) -> Route<B2, E2> + Send { clone_box(&self) -> Box<dyn LayerFn<B, E, B2, E2>>183 fn clone_box(&self) -> Box<dyn LayerFn<B, E, B2, E2>>; 184 } 185 186 impl<F, B, E, B2, E2> LayerFn<B, E, B2, E2> for F 187 where 188 F: FnOnce(Route<B, E>) -> Route<B2, E2> + Clone + Send + 'static, 189 { clone_box(&self) -> Box<dyn LayerFn<B, E, B2, E2>>190 fn clone_box(&self) -> Box<dyn LayerFn<B, E, B2, E2>> { 191 Box::new(self.clone()) 192 } 193 } 194