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
mod raw_route;
pub use raw_route::{RawRoute, HyperRequest};

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

mod catcher;
pub use catcher::Catcher;

pub mod util;

use crate::header::RequestHeader;

use std::slice;


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


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

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

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

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

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

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

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

	pub fn catchers(&self) -> slice::Iter<'_, BoxedCatcher> {
		self.catcher.iter()
	}
}