thruster_core/route_tree/
mod.rs1mod node;
2
3use std::collections::HashMap;
4
5pub use self::node::Node;
6use crate::context::Context;
7use thruster_core_async_await::{MiddlewareChain};
8
9pub enum Method {
10 DELETE,
11 GET,
12 OPTIONS,
13 POST,
14 PUT,
15 UPDATE
16}
17
18pub struct RouteTree<T: 'static + Context + Send> {
19 pub root_node: Node<T>,
20 pub generic_root_node: Node<T>,
21 pub specific_root_node: Node<T>
22}
23
24fn method_to_prefix<'a>(method: &Method) -> &'a str {
25 match method {
26 Method::DELETE => "__DELETE__",
27 Method::GET => "__GET__",
28 Method::OPTIONS => "__OPTIONS__",
29 Method::POST => "__POST__",
30 Method::PUT => "__PUT__",
31 Method::UPDATE => "__UPDATE__"
32 }
33}
34
35impl<T: 'static + Context + Send> RouteTree<T> {
36 pub fn new() -> RouteTree<T> {
37 RouteTree {
38 root_node: Node::new(""),
39 generic_root_node: Node::new(""),
40 specific_root_node: Node::new("")
41 }
42 }
43
44 pub fn update_root_node(&mut self) {
50 let mut root_node = self.specific_root_node.clone();
51
52 root_node.push_middleware_to_populated_nodes(&self.generic_root_node, &MiddlewareChain::new());
53
54 self.root_node = root_node;
55 }
56
57 pub fn add_use_node(&mut self, route: &str, middleware: MiddlewareChain<T>) {
58 self.generic_root_node.add_route(route, middleware);
59 self.update_root_node();
60 }
61
62 pub fn add_route_with_method(&mut self, method: &Method, route: &str, middleware: MiddlewareChain<T>) {
63 let prefix = method_to_prefix(&method);
64
65 let full_route = format!("{}{}", prefix, route);
66
67 self.specific_root_node.add_route(&full_route, middleware);
68 self.update_root_node();
69 }
70
71 pub fn add_route(&mut self, route: &str, middleware: MiddlewareChain<T>) {
72 self.specific_root_node.add_route(route, middleware);
73 self.update_root_node();
74 }
75
76 fn _adopt_sub_app_method_to_self(&mut self, route: &str, mut route_tree: RouteTree<T>, method: &Method) -> RouteTree<T> {
77 let method_prefix = method_to_prefix(&method);
78
79 let mut self_routes = self.specific_root_node.children.remove(method_prefix)
80 .unwrap_or_else(|| Node::new(method_prefix));
81
82 if let Some(tree_routes) = route_tree.root_node.children.remove(method_prefix) {
83 self_routes.add_subtree(route, tree_routes);
84 }
85
86 self.specific_root_node.children.insert(method_prefix.to_owned(), self_routes);
87
88 route_tree
90 }
91
92 pub fn add_route_tree(&mut self, route: &str, mut route_tree: RouteTree<T>) {
93 route_tree = self._adopt_sub_app_method_to_self(route, route_tree, &Method::DELETE);
94 route_tree = self._adopt_sub_app_method_to_self(route, route_tree, &Method::GET);
95 route_tree = self._adopt_sub_app_method_to_self(route, route_tree, &Method::OPTIONS);
96 route_tree = self._adopt_sub_app_method_to_self(route, route_tree, &Method::POST);
97 route_tree = self._adopt_sub_app_method_to_self(route, route_tree, &Method::PUT);
98 self._adopt_sub_app_method_to_self(route, route_tree, &Method::UPDATE);
99 self.update_root_node();
100 }
101
102 pub fn match_route(&self, route: &str) -> (HashMap<String, String>, &MiddlewareChain<T>) {
103 let results = self.root_node.match_route(route.split('/'));
104
105 (results.0, results.2)
106 }
107
108 pub fn match_route_with_params(&self, route: &str, params: HashMap<String, String>) -> (HashMap<String, String>, &MiddlewareChain<T>) {
109 let results = self.root_node.match_route_with_params(route.split('/'), params);
110
111 (results.0, results.2)
112 }
113}
114
115impl<T: 'static + Context + Send> Default for RouteTree<T> {
116 fn default() -> RouteTree<T> {
117 RouteTree::new()
118 }
119}