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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
mod node;
use std::collections::HashMap;
pub use self::node::Node;
use crate::context::Context;
use thruster_core_async_await::{MiddlewareChain};
pub enum Method {
DELETE,
GET,
OPTIONS,
POST,
PUT,
UPDATE
}
pub struct RouteTree<T: 'static + Context + Send> {
pub root_node: Node<T>,
pub generic_root_node: Node<T>,
pub specific_root_node: Node<T>
}
fn method_to_prefix<'a>(method: &Method) -> &'a str {
match method {
Method::DELETE => "__DELETE__",
Method::GET => "__GET__",
Method::OPTIONS => "__OPTIONS__",
Method::POST => "__POST__",
Method::PUT => "__PUT__",
Method::UPDATE => "__UPDATE__"
}
}
impl<T: 'static + Context + Send> RouteTree<T> {
pub fn new() -> RouteTree<T> {
RouteTree {
root_node: Node::new(""),
generic_root_node: Node::new(""),
specific_root_node: Node::new("")
}
}
pub fn update_root_node(&mut self) {
let mut root_node = self.specific_root_node.clone();
root_node.push_middleware_to_populated_nodes(&self.generic_root_node, &MiddlewareChain::new());
self.root_node = root_node;
}
pub fn add_use_node(&mut self, route: &str, middleware: MiddlewareChain<T>) {
self.generic_root_node.add_route(route, middleware);
self.update_root_node();
}
pub fn add_route_with_method(&mut self, method: &Method, route: &str, middleware: MiddlewareChain<T>) {
let prefix = method_to_prefix(&method);
let full_route = format!("{}{}", prefix, route);
self.specific_root_node.add_route(&full_route, middleware);
self.update_root_node();
}
pub fn add_route(&mut self, route: &str, middleware: MiddlewareChain<T>) {
self.specific_root_node.add_route(route, middleware);
self.update_root_node();
}
fn _adopt_sub_app_method_to_self(&mut self, route: &str, mut route_tree: RouteTree<T>, method: &Method) -> RouteTree<T> {
let method_prefix = method_to_prefix(&method);
let mut self_routes = self.specific_root_node.children.remove(method_prefix)
.unwrap_or_else(|| Node::new(method_prefix));
if let Some(tree_routes) = route_tree.root_node.children.remove(method_prefix) {
self_routes.add_subtree(route, tree_routes);
}
self.specific_root_node.children.insert(method_prefix.to_owned(), self_routes);
route_tree
}
pub fn add_route_tree(&mut self, route: &str, mut route_tree: RouteTree<T>) {
route_tree = self._adopt_sub_app_method_to_self(route, route_tree, &Method::DELETE);
route_tree = self._adopt_sub_app_method_to_self(route, route_tree, &Method::GET);
route_tree = self._adopt_sub_app_method_to_self(route, route_tree, &Method::OPTIONS);
route_tree = self._adopt_sub_app_method_to_self(route, route_tree, &Method::POST);
route_tree = self._adopt_sub_app_method_to_self(route, route_tree, &Method::PUT);
self._adopt_sub_app_method_to_self(route, route_tree, &Method::UPDATE);
self.update_root_node();
}
pub fn match_route(&self, route: &str) -> (HashMap<String, String>, &MiddlewareChain<T>) {
let results = self.root_node.match_route(route.split('/'));
(results.0, results.2)
}
pub fn match_route_with_params(&self, route: &str, params: HashMap<String, String>) -> (HashMap<String, String>, &MiddlewareChain<T>) {
let results = self.root_node.match_route_with_params(route.split('/'), params);
(results.0, results.2)
}
}
impl<T: 'static + Context + Send> Default for RouteTree<T> {
fn default() -> RouteTree<T> {
RouteTree::new()
}
}