1
2
3use crate::prelude::*;
4
5
6
7
8#[ derive (Clone) ]
9#[ cfg (feature = "hss-routes") ]
10pub struct Routes {
11 internals : RoutesInternals,
12}
13
14#[ cfg (feature = "hss-routes") ]
15struct RoutesInternals0 {
16 tree : path_tree::PathTree<Arc<Route>>,
17 list : Vec<Arc<Route>>,
18 fallback : Option<HandlerDynArc>,
19}
20
21#[ cfg (feature = "hss-routes") ]
22type RoutesInternals = Arc<RoutesInternals0>;
23
24
25
26
27#[ cfg (feature = "hss-routes") ]
28impl Routes {
29
30 pub fn builder () -> RoutesBuilder {
31 RoutesBuilder::new ()
32 }
33
34 pub fn into_builder (self) -> RoutesBuilder {
35 let _routes = self.internals.list.clone ();
36 let _fallback = self.internals.fallback.clone ();
37 RoutesBuilder {
38 routes : _routes,
39 fallback : _fallback,
40 }
41 }
42
43 pub fn resolve (&self, _path : &str) -> ServerResult<Option<RouteMatched>> {
44 if let Some ((_route, _parameters)) = self.internals.tree.find (_path) {
45 let _route = _route.clone ();
46 let _parameters = _parameters.into_iter () .map (|(_name, _value)| (String::from (_name), String::from (_value))) .collect ();
47 let _matched = RouteMatched {
48 routes : self.clone (),
49 route : _route,
50 parameters : _parameters,
51 };
52 Ok (Some (_matched))
53 } else {
54 Ok (None)
55 }
56 }
57
58 pub fn routes (&self) -> impl Iterator<Item = &Arc<Route>> {
59 self.internals.list.iter ()
60 }
61
62 pub fn handle (&self, _request : Request<Body>) -> HandlerFutureDynBox {
63 match self.try_handle (_request) {
64 Ok (_future) =>
65 _future,
66 Err (_request) =>
67 HandlerFutureDynBox::ready_error (error_with_format (0x15c0a773, format_args! ("no route matched for `{}`", _request.uri () .path ()))),
68 }
69 }
70
71 pub fn try_handle (&self, _request : Request<Body>) -> Result<HandlerFutureDynBox, Request<Body>> {
72 let _path = _request.uri () .path ();
73 let _route_matched = match self.resolve (_path) {
74 Ok (_route_matched) =>
75 _route_matched,
76 Err (_error) =>
77 return Ok (HandlerFutureDynBox::ready_error (_error)),
78 };
79 if let Some (_route_matched) = _route_matched {
80 let _route = _route_matched.route.clone ();
81 Ok (_route.handle (_request, _route_matched))
82 } else if let Some (_fallback) = self.internals.fallback.as_ref () {
83 Ok (_fallback.delegate (_request))
84 } else {
85 Err (_request)
86 }
87 }
88}
89
90
91#[ cfg (feature = "hss-routes") ]
92impl Route {
93
94 pub fn handle (&self, _request : Request<Body>, _route_matched : RouteMatched) -> HandlerFutureDynBox {
95 let mut _request = _request;
96 match self.handler {
97 RouteHandler::HandlerDynArc (ref _handler) => {
98 _request.extensions_mut () .insert (_route_matched);
99 _handler.handle (_request)
100 }
101 RouteHandler::RouteHandlerDynArc (ref _handler) =>
102 _handler.handle (_request, _route_matched),
103 }
104 }
105}
106
107
108#[ cfg (feature = "hss-routes") ]
109impl Handler for Routes {
110
111 type Future = HandlerFutureDynBox;
112 type ResponseBody = BodyDynBox;
113 type ResponseBodyError = ServerError;
114
115 fn handle (&self, _request : Request<Body>) -> Self::Future {
116 Routes::handle (self, _request)
117 }
118}
119
120
121
122
123#[ cfg (feature = "hss-routes") ]
124pub struct RoutesBuilder {
125 pub routes : Vec<Arc<Route>>,
126 pub fallback : Option<HandlerDynArc>,
127}
128
129
130#[ cfg (feature = "hss-routes") ]
131impl RoutesBuilder {
132
133 pub fn new () -> Self {
134 Self {
135 routes : Vec::new (),
136 fallback : None,
137 }
138 }
139
140 pub fn build (self) -> ServerResult<Routes> {
141
142 let _routes = self.routes;
143 let mut _fallback = self.fallback;
144
145 let mut _tree = path_tree::PathTree::new ();
146 let mut _list = Vec::with_capacity (_routes.len ());
147
148 for _route in _routes.into_iter () {
149 if _route.path.is_empty () {
150 if _fallback.is_some () {
151 return Err (error_with_message (0x073a9b1a, "multiple fallback routes specified"));
152 }
153 _fallback = match _route.handler {
154 RouteHandler::HandlerDynArc (ref _handler) =>
155 Some (HandlerDynArc::from_arc (_handler.clone ())),
156 RouteHandler::RouteHandlerDynArc (_) =>
157 return Err (error_with_message (0x6e5e324e, "invalid fallback route specified")),
158 };
159 } else {
160 _tree.insert (&_route.path, _route.clone ());
161 _list.push (_route);
162 }
163 }
164
165 let _self = RoutesInternals0 {
166 tree : _tree,
167 list : _list,
168 fallback : _fallback,
169 };
170 let _self = Routes {
171 internals : Arc::new (_self),
172 };
173
174 Ok (_self)
175 }
176
177 #[ allow (single_use_lifetimes) ]
178 pub fn with_route <'a, P, H, F, RB> (self, _paths : P, _handler : H) -> Self
179 where
180 P : Into<RoutePaths<'a>>,
181 H : Handler<Future = F, ResponseBody = RB, ResponseBodyError = RB::Error> + Send + Sync + 'static,
182 F : Future<Output = ServerResult<Response<RB>>> + Send + 'static,
183 RB : BodyTrait<Data = Bytes> + Send + Sync + 'static,
184 RB::Error : Error + Send + Sync + 'static,
185 {
186 let _handler : H = _handler.into ();
187 self.with_route_dyn (_paths, _handler)
188 }
189
190 #[ allow (single_use_lifetimes) ]
191 pub fn with_route_fn_sync <'a, P, I, C, RB> (self, _paths : P, _handler : I) -> Self
192 where
193 P : Into<RoutePaths<'a>>,
194 I : Into<HandlerFnSync<C, RB>>,
195 C : Fn (Request<Body>) -> ServerResult<Response<RB>> + Send + Sync + 'static,
196 RB : BodyTrait<Data = Bytes> + Send + Sync + 'static,
197 RB::Error : Error + Send + Sync + 'static,
198 {
199 let _handler : HandlerFnSync<C, RB> = _handler.into ();
200 self.with_route_dyn (_paths, _handler)
201 }
202
203 #[ allow (single_use_lifetimes) ]
204 pub fn with_route_fn_async <'a, P, I, C, F, RB> (self, _paths : P, _handler : I) -> Self
205 where
206 P : Into<RoutePaths<'a>>,
207 I : Into<HandlerFnAsync<C, F, RB>>,
208 C : Fn (Request<Body>) -> F + Send + Sync + 'static,
209 F : Future<Output = ServerResult<Response<RB>>> + Send + 'static,
210 RB : BodyTrait<Data = Bytes> + Send + Sync + 'static,
211 RB::Error : Error + Send + Sync + 'static,
212 {
213 let _handler : HandlerFnAsync<C, F, RB> = _handler.into ();
214 self.with_route_dyn (_paths, _handler)
215 }
216
217 #[ allow (single_use_lifetimes) ]
218 pub fn with_route_fn_response <'a, P, C, RB> (self, _paths : P, _handler : C) -> Self
219 where
220 P : Into<RoutePaths<'a>>,
221 C : Fn () -> Response<RB> + Send + Sync + 'static,
222 RB : BodyTrait<Data = Bytes> + Send + Sync + 'static,
223 RB::Error : Error + Send + Sync + 'static,
224 {
225 self.with_route_fn_sync (_paths, move |_request| Ok (_handler ()))
226 }
227
228 #[ allow (single_use_lifetimes) ]
229 pub fn with_route_dyn <'a, P, H> (self, _paths : P, _handler : H) -> Self
230 where
231 H : HandlerDyn,
232 P : Into<RoutePaths<'a>>,
233 {
234 let _handler : H = _handler.into ();
235 let _handler = HandlerDynArc::new (_handler);
236 self.with_route_arc (_paths, _handler)
237 }
238
239 #[ allow (single_use_lifetimes) ]
240 pub fn with_route_arc <'a, P, I> (mut self, _paths : P, _handler : I) -> Self
241 where
242 I : Into<HandlerDynArc>,
243 P : Into<RoutePaths<'a>>,
244 {
245 let mut _paths = _paths.into ();
246 let _handler = _handler.into ();
247 while let Some (_path) = _paths.next () {
248 let _route = Route {
249 path : String::from (_path),
250 handler : RouteHandler::HandlerDynArc (_handler.clone_arc ()),
251 extensions : http::Extensions::new (),
252 };
253 self = self.with_route_object (_route);
254 }
255 self
256 }
257
258 pub fn with_route_object (mut self, _route : Route) -> Self {
259 let _route = Arc::new (_route);
260 self.routes.push (_route);
261 self
262 }
263}
264
265
266
267
268#[ cfg (feature = "hss-routes") ]
269pub struct Route {
270 pub path : String,
271 pub handler : RouteHandler,
272 pub extensions : Extensions,
273}
274
275
276
277
278#[ derive (Clone) ]
279#[ cfg (feature = "hss-routes") ]
280pub enum RouteHandler {
281 HandlerDynArc (Arc<dyn HandlerDyn>),
282 RouteHandlerDynArc (Arc<dyn RouteHandlerDyn>),
283}
284
285
286
287
288#[ cfg (feature = "hss-routes") ]
289pub trait RouteHandlerDyn
290 where
291 Self : Send + Sync + 'static,
292{
293 fn handle (&self, _request : Request<Body>, _route : RouteMatched) -> HandlerFutureDynBox;
294}
295
296
297
298
299#[ derive (Clone) ]
300#[ cfg (feature = "hss-routes") ]
301pub struct RouteMatched {
302 pub routes : Routes,
303 pub route : Arc<Route>,
304 pub parameters : Vec<(String, String)>,
305}
306
307
308#[ cfg (feature = "hss-routes") ]
309impl RouteMatched {
310
311
312 pub fn parameter_nth (&self, _index : usize) -> &String {
313 & (self.parameters.get (_index) .or_panic (0xe86a76a8)) .1
314 }
315
316 pub fn parameters_1 (&self) -> &String {
317 self.parameter_nth (0)
318 }
319
320 pub fn parameters_2 (&self) -> (&String, &String) {
321 (
322 self.parameter_nth (0),
323 self.parameter_nth (1),
324 )
325 }
326
327 pub fn parameters_3 (&self) -> (&String, &String, &String) {
328 (
329 self.parameter_nth (0),
330 self.parameter_nth (1),
331 self.parameter_nth (2),
332 )
333 }
334
335 pub fn parameters_4 (&self) -> (&String, &String, &String, &String) {
336 (
337 self.parameter_nth (0),
338 self.parameter_nth (1),
339 self.parameter_nth (2),
340 self.parameter_nth (3),
341 )
342 }
343
344
345 pub fn resolve_parameter_nth (_request : &Request<Body>, _index : usize) -> &String {
346 Self::resolve_or_panic (_request) .parameter_nth (_index)
347 }
348
349 pub fn resolve_parameters_1 (_request : &Request<Body>) -> &String {
350 Self::resolve_or_panic (_request) .parameters_1 ()
351 }
352
353 pub fn resolve_parameters_2 (_request : &Request<Body>) -> (&String, &String) {
354 Self::resolve_or_panic (_request) .parameters_2 ()
355 }
356
357 pub fn resolve_parameters_3 (_request : &Request<Body>) -> (&String, &String, &String) {
358 Self::resolve_or_panic (_request) .parameters_3 ()
359 }
360
361 pub fn resolve_parameters_4 (_request : &Request<Body>) -> (&String, &String, &String, &String) {
362 Self::resolve_or_panic (_request) .parameters_4 ()
363 }
364
365 pub fn resolve (_request : &Request<Body>) -> Option<&Self> {
366 _request.extensions () .get ()
367 }
368
369 fn resolve_or_panic (_request : &Request<Body>) -> &Self {
370 Self::resolve (_request) .or_panic (0x4c9197b5)
371 }
372}
373
374
375
376
377#[ cfg (feature = "hss-routes") ]
378pub enum RoutePaths <'a> {
379 Single (&'a str),
380 Slice (&'a [&'a str]),
381 Fallback,
382 None,
383}
384
385
386#[ cfg (feature = "hss-routes") ]
387impl <'a> RoutePaths<'a> {
388
389 fn next (&mut self) -> Option<&'a str> {
390 match self {
391 RoutePaths::Single (_path) => {
392 let _path = *_path;
393 *self = RoutePaths::None;
394 Some (_path)
395 }
396 RoutePaths::Slice (_paths) => {
397 if let Some ((_first, _rest)) = _paths.split_first () {
398 *self = RoutePaths::Slice (_rest);
399 Some (_first)
400 } else {
401 *self = RoutePaths::None;
402 None
403 }
404 }
405 RoutePaths::Fallback => {
406 *self = RoutePaths::None;
407 Some ("")
408 }
409 RoutePaths::None =>
410 None,
411 }
412 }
413}
414
415#[ cfg (feature = "hss-routes") ]
416impl <'a> From<&'a str> for RoutePaths<'a> {
417 fn from (_path : &'a str) -> Self {
418 RoutePaths::Single (_path)
419 }
420}
421
422#[ cfg (feature = "hss-routes") ]
423impl <'a> From<&'a [&'a str]> for RoutePaths<'a> {
424 fn from (_paths : &'a [&'a str]) -> Self {
425 RoutePaths::Slice (_paths)
426 }
427}
428
429#[ cfg (feature = "hss-routes") ]
430impl <'a> From<&'a [&'a str; 2]> for RoutePaths<'a> {
431 fn from (_paths : &'a [&'a str; 2]) -> Self {
432 RoutePaths::Slice (&_paths[..])
433 }
434}
435#[ cfg (feature = "hss-routes") ]
436impl <'a> From<&'a [&'a str; 3]> for RoutePaths<'a> {
437 fn from (_paths : &'a [&'a str; 3]) -> Self {
438 RoutePaths::Slice (&_paths[..])
439 }
440}
441#[ cfg (feature = "hss-routes") ]
442impl <'a> From<&'a [&'a str; 4]> for RoutePaths<'a> {
443 fn from (_paths : &'a [&'a str; 4]) -> Self {
444 RoutePaths::Slice (&_paths[..])
445 }
446}
447#[ cfg (feature = "hss-routes") ]
448impl <'a> From<&'a [&'a str; 5]> for RoutePaths<'a> {
449 fn from (_paths : &'a [&'a str; 5]) -> Self {
450 RoutePaths::Slice (&_paths[..])
451 }
452}
453