1use std::any::Any;
2use std::fmt::{Debug, Formatter};
3use std::ops::Deref;
4use crate::net::Fresh;
5use crate::server::{Handler, Request, Response};
6use crate::status::StatusCode;
7use crate::uri::RequestUri::AbsolutePath;
8use std::sync::Arc;
9use crate::runtime::{SyncHashMap, SyncVec};
10use crate::uri::RequestUri;
11
12pub struct HandleBox {
13 pub url: String,
14 pub inner: Box<dyn Handler>,
15}
16
17impl Debug for HandleBox {
18 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
19 f.debug_struct("HandleBox")
20 .field("url", &self.url)
21 .field("inner", &"*")
22 .finish()
23 }
24}
25
26pub trait MiddleWare: Send + Sync {
27 fn handle(&self, req: &mut Request, res: &mut Option<Response>);
29}
30
31impl<T: MiddleWare> MiddleWare for Arc<T> {
32 fn handle(&self, req: &mut Request, res: &mut Option<Response>) {
33 T::handle(self, req, res)
34 }
35}
36
37impl<F> MiddleWare for F where F: Fn(&mut Request, &mut Option<Response>), F: Sync + Send {
38 fn handle(&self, req: &mut Request, res: &mut Option<Response>) {
39 self(req, res)
40 }
41}
42
43pub struct Route {
44 pub container: SyncHashMap<String, Arc<Box<dyn Any>>>,
45 pub middleware: SyncVec<Box<dyn MiddleWare>>,
46 pub handlers: SyncHashMap<String, HandleBox>,
47}
48
49impl Debug for Route {
50 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
51 f.debug_struct("Route")
52 .field("container", &self.container.len())
53 .field("middleware", &self.middleware.len())
54 .field("handlers", &self.handlers)
55 .finish()
56 }
57}
58
59
60impl Route {
61 pub fn new() -> Self {
62 Self {
63 container: SyncHashMap::new(),
64 middleware: SyncVec::new(),
65 handlers: SyncHashMap::new(),
66 }
67 }
68 pub fn handle_fn<H: Handler + 'static>(&self, url: &str, h: H) {
89 self.handlers.insert(url.to_string(), HandleBox {
90 url: url.to_string(),
91 inner: Box::new(h),
92 });
93 }
94
95 pub fn add_middleware<M: MiddleWare + 'static>(&self, m: M) {
106 self.middleware.push(Box::new(m));
107 }
108
109 pub fn insert<T: Any>(&self, key: &str, data: T) {
110 self.container.insert(key.to_string(), Arc::new(Box::new(data)));
111 }
112
113 pub fn get<T: Any>(&self, key: &str) -> Option<&T> {
114 match self.container.get(key) {
115 None => {
116 None
117 }
118 Some(b) => {
119 let r: Option<&T> = b.downcast_ref();
120 r
121 }
122 }
123 }
124
125 pub fn index<T: Any>(&self, key: &str) -> &T {
127 self.get(key).expect(&format!("key:{} Does not exist in the container", key))
128 }
129}
130
131
132impl Handler for Route {
133 fn handle<'a, 'k>(&'a self, mut req: Request<'a, 'k>, mut res: Response<'a, Fresh>){
134 for m in &self.middleware {
135 let mut r = Some(res);
136 m.handle(&mut req, &mut r);
138 if r.is_none() {
139 return;
140 } else {
141 res = r.unwrap();
142 }
143 }
144 match &req.uri {
145 AbsolutePath(p) => {
146 let path = &p[0..p.find("?").unwrap_or(p.len())];
147 match self.handlers.get(path) {
148 None => {
149 res.status = StatusCode::NotFound;
151 return;
152 }
153 Some(h) => {
154 let i = &h.inner;
155 i.handle(req, res);
156 return;
157 }
158 }
159 }
160 RequestUri::AbsoluteUri(_) => {}
161 RequestUri::Authority(_) => {}
162 RequestUri::Star => {}
163 }
164 }
165}
166
167impl Handler for Arc<Route> {
168 fn handle<'a, 'k>(&'a self, req: Request<'a, 'k>, res: Response<'a, Fresh>) {
169 self.deref().handle(req,res)
170 }
171}