hyper_simple_server/
routes.rs

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