1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

mod raw_route;
pub use raw_route::RawRoute;

mod route;
pub use route::{Route, check_static};

mod catcher;
pub use catcher::Catcher;

use crate::request::HyperRequest;

use http::header::{ RequestHeader, ResponseHeader };


type BoxedRawRoute<D> = Box<dyn RawRoute<D>>;
type BoxedRoute<D> = Box<dyn Route<D>>;
type BoxedCatcher<D> = Box<dyn Catcher<D>>;


pub struct Routes<D> {
	// maybe store static routes in hashmap??
	raw: Vec<BoxedRawRoute<D>>,
	basic: Vec<BoxedRoute<D>>,
	catcher: Vec<BoxedCatcher<D>>
}

impl<D> Routes<D> {

	pub fn new() -> Self {
		Self{
			raw: vec![],
			basic: vec![],
			catcher: vec![]
		}
	}

	pub fn push_raw<R>(&mut self, route: R)
	where R: RawRoute<D> + 'static {
		self.raw.push(Box::new(route))
	}

	pub fn push<R>(&mut self, route: R)
	where R: Route<D> + 'static {
		self.basic.push(Box::new(route))
	}

	pub fn push_catcher<C>(&mut self, catcher: C)
	where C: Catcher<D> + 'static {
		self.catcher.push(Box::new(catcher))
	}

	pub fn route_raw(
		&self,
		hyper_request: &HyperRequest
	) -> Option<&BoxedRawRoute<D>> {
		for route in &self.raw {
			if route.check(hyper_request) {
				return Some(route)
			}
		}
		None
	}

	pub fn route(
		&self,
		request_header: &RequestHeader
	) -> Option<&BoxedRoute<D>> {
		for route in &self.basic {
			if route.check( request_header ) {
				return Some( route )
			}
		}
		None
	}

	pub fn route_catcher(
		&self,
		request_header: &RequestHeader,
		response_header: &ResponseHeader
	) -> Option<&BoxedCatcher<D>> {
		for catcher in &self.catcher {
			if catcher.check(request_header, response_header) {
				return Some(catcher)
			}
		}
		None
	}

}