1
2use std::collections::HashMap;
3
4use crate::context::Context;
5
6pub type Handler = fn(&mut Context);
7
8pub struct Router {
10 pub fallback: Handler,
11 routes: HashMap<String, HashMap<String, Handler>>,
12}
13
14fn not_implemented(ctx: &mut Context) {
15 eprintln!("ERROR: default fallback handler fired, you probably mean to replace this.");
16 ctx.response_mut().code = "501";
17 ctx.response_mut().body = b"<h1>501: Not Implemented</h1>".to_vec();
18}
19
20impl Default for Router {
21 fn default() -> Self {
22 Self::new()
23 }
24}
25
26impl Router {
27 pub fn new() -> Self {
29 Self {
30 fallback: not_implemented,
31 routes: HashMap::new(),
32 }
33 }
34
35 pub fn register(&mut self, method: &str, route: &str, func: Handler) -> bool {
38 if !self.routes.contains_key(method) {
39 self.routes.insert(method.to_string(), HashMap::new());
40 }
41 match self.routes.get_mut(method) {
42 None => return false,
43 Some(inner) => inner,
44 }.insert(route.to_string(), func);
45 true
46 }
47
48 pub fn unregister(&mut self, method: &str, route: &str) -> bool {
50 match self.routes.get_mut(method) {
51 None => false,
52 Some(inner) => {
53 inner.remove(route).is_some()
54 },
55 }
56 }
57
58 pub fn call(&self, ctx: &mut Context) {
62 let method = ctx.request().method;
63 let document = ctx.request().document;
64
65 if ctx.response().is_redirect() {
66 return;
67 }
68 let by_method = match self.routes.get(method) {
69 None => {
70 (self.fallback)(ctx);
71 return;
72 },
73 Some(inner) => inner,
74 };
75 let func = match by_method.get(document) {
76 None => {
77 (self.fallback)(ctx);
78 return;
79 },
80 Some(inner) => inner,
81 };
82 func(ctx);
83 }
84}
85