thruster_core/
route_parser.rs1use std::collections::HashMap;
2
3use crate::context::Context;
4use crate::route_tree::RouteTree;
5
6use thruster_core_async_await::{MiddlewareChain};
7
8pub struct MatchedRoute<'a, T: 'static + Context + Send> {
9 pub middleware: &'a MiddlewareChain<T>,
10 pub value: String,
11 pub params: HashMap<String, String>,
12 pub query_params: HashMap<String, String>,
13}
14
15pub struct RouteParser<T: 'static + Context + Send> {
16 pub route_tree: RouteTree<T>,
17 pub shortcuts: HashMap<String, MiddlewareChain<T>>
18}
19
20impl<T: Context + Send> RouteParser<T> {
21 pub fn new() -> RouteParser<T> {
22 RouteParser {
23 route_tree: RouteTree::new(),
24 shortcuts: HashMap::new()
25 }
26 }
27
28 pub fn add_method_agnostic_middleware(&mut self, route: &str, middleware: MiddlewareChain<T>) {
29 self.route_tree.add_use_node(route, middleware);
30 }
31
32 pub fn add_route(&mut self, route: &str, middleware: MiddlewareChain<T>) {
33 self.route_tree.add_route(route, middleware);
34 }
35
36 pub fn optimize(&mut self) {
37 let routes = self.route_tree.root_node.get_route_list();
38
39 for (path, middleware, is_terminal_node) in routes {
40 if is_terminal_node {
41 self.shortcuts.insert((&path[1..]).to_owned(), middleware);
42 }
43 }
44 }
45
46 #[inline]
47 pub fn match_route(&self, route: &str) -> MatchedRoute<T> {
48 let query_params = HashMap::new();
49
50 let split_route = route.find('?');
51 let mut route = match split_route {
52 Some(index) => &route[0..index],
53 None => route
54 };
55
56 while &route[route.len() - 1..route.len()] == "/" {
58 route = &route[0..route.len() - 1];
59 }
60
61 if let Some(shortcut) = self.shortcuts.get(route) {
62 MatchedRoute {
63 middleware: shortcut,
64 value: route.to_owned(),
65 params: HashMap::new(),
66 query_params
67 }
68 } else {
69 let matched = self.route_tree.match_route(route);
70
71 MatchedRoute {
72 middleware: matched.1,
73 value: route.to_owned(),
74 params: matched.0,
75 query_params
76 }
77 }
78 }
79}
80
81impl<T: Context + Send> Default for RouteParser<T> {
82 fn default() -> RouteParser<T> {
83 RouteParser::new()
84 }
85}