1use crate::middleware::matchable_middleware::MatchableMiddleware;
2use crate::{ErrorMiddleware, Middleware, Request, Response};
3use hyper::{http::StatusCode, Body};
4
5struct Chain<'a, T> {
6 middleware: &'a Vec<Middleware<T>>,
7 error_middleware: &'a Vec<ErrorMiddleware<T>>,
8}
9
10#[derive(PartialEq)]
11enum NextFunctionResult {
12 None,
13 Success,
14 Failure(String),
15}
16
17impl<'a, T> Chain<'a, T> {
18 pub fn new(
19 middleware: &'a Vec<Middleware<T>>,
20 error_middleware: &'a Vec<ErrorMiddleware<T>>,
21 ) -> Chain<'a, T> {
22 Chain {
23 middleware,
24 error_middleware,
25 }
26 }
27
28 pub fn run(&mut self, req: &mut Request<T>, res: &mut Response) {
29 let matching_middleware: Vec<&Middleware<T>> = self
30 .middleware
31 .into_iter()
32 .filter(|m| m.is_match(req))
33 .collect();
34
35 if matching_middleware.len() > 0 {
36 self.handle_success(matching_middleware, req, res);
37 } else {
38 self.handle_error("Not found".to_string(), req, res, StatusCode::NOT_FOUND);
39 }
40 }
41
42 fn handle_success(
43 &self,
44 matching_middleware: Vec<&Middleware<T>>,
45 req: &mut Request<T>,
46 res: &mut Response,
47 ) {
48 for middleware in matching_middleware.iter() {
49 let mut next_function_result = NextFunctionResult::None;
50
51 let mut next = |result: Result<(), String>| {
52 if let Err(err) = result {
53 next_function_result = NextFunctionResult::Failure(err)
54 } else {
55 next_function_result = NextFunctionResult::Success;
56 }
57 };
58
59 req.set_base_url(middleware.base_url);
60 middleware.invoke(req, res, &mut next);
61
62 match next_function_result {
63 NextFunctionResult::Success => (),
64 NextFunctionResult::Failure(err) => {
65 self.handle_error(err, req, res, StatusCode::INTERNAL_SERVER_ERROR)
66 }
67 NextFunctionResult::None => {
68 if !res.ended {
70 panic!("next function never called.")
71 }
72 }
73 }
74 }
75 }
76
77 fn handle_error(
78 &self,
79 error: String,
80 req: &mut Request<T>,
81 res: &mut Response,
82 fallback_status_code: StatusCode,
83 ) {
84 let mut error = error;
85 let matching_error_middleware: Vec<&ErrorMiddleware<T>> = self
86 .error_middleware
87 .into_iter()
88 .filter(|m| m.is_match(req))
89 .collect();
90
91 res.status(fallback_status_code);
92
93 if matching_error_middleware.len() > 0 {
94 for middleware in matching_error_middleware.iter() {
95 let mut next_function_result = NextFunctionResult::None;
96
97 let mut next = |result: Result<(), String>| {
98 if let Err(err) = result {
99 next_function_result = NextFunctionResult::Failure(err)
100 } else {
101 next_function_result = NextFunctionResult::Success;
102 }
103 };
104
105 req.set_base_url(middleware.base_url);
106 middleware.invoke(&error, req, res, &mut next);
107
108 match next_function_result {
109 NextFunctionResult::Success => {
111 panic!("next function can not be called without an error in use_err");
112 }
113 NextFunctionResult::Failure(new_error) => {
114 error = new_error;
115 }
116 NextFunctionResult::None => {
117 if !res.ended {
119 panic!("next function never called.")
120 }
121 }
122 }
123 }
124 } else {
125 res.end();
126 }
127 }
128}
129
130pub async fn run<T>(
131 _req: hyper::Request<Body>,
132 middleware: &Vec<Middleware<T>>,
133 error_middleware: &Vec<ErrorMiddleware<T>>,
134 app_locals: &Option<T>,
135) -> hyper::Response<Body> {
136 let mut req = Request::from(_req);
137 req.with_app_locals(app_locals);
138 let mut res = Response::new();
139
140 let mut chain = Chain::new(middleware, error_middleware);
141 chain.run(&mut req, &mut res);
142
143 res.into()
144}