1use crate::common::{collect_error_middleware, collect_middleware};
2use crate::core::run;
3use crate::{Error, NextFunction, Request, Response, Router};
4use hyper::{
5 server::Server,
6 service::{make_service_fn, service_fn},
7};
8use log::info;
9use std::convert::Infallible;
10use std::sync::Arc;
11
12static LOCALHOST_ADDRESS_OCTETS: &'static [u8; 4] = &[127, 0, 0, 1];
13
14pub struct App<T> {
16 pub(crate) locals: Option<T>,
17 pub(crate) routers: Vec<Router<T>>,
18}
19
20impl<T: Send + Sync + 'static> App<T> {
21 pub fn new() -> App<T> {
24 App {
25 locals: None,
26 routers: vec![Router::new("/")],
27 }
28 }
29
30 pub async fn listen(
44 mut self,
45 port: u16,
46 ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
47 let addr = (LOCALHOST_ADDRESS_OCTETS.clone(), port).into();
48 let middleware = collect_middleware(&mut self);
49 let error_middleware = collect_error_middleware(&mut self);
50
51 let middleware = Arc::new(middleware);
52 let error_middleware = Arc::new(error_middleware);
53 let app_locals = Arc::new(self.locals);
54
55 let server = Server::bind(&addr).serve(make_service_fn(move |_conn| {
56 let middleware = middleware.clone();
57 let error_middleware = error_middleware.clone();
58 let app_locals = app_locals.clone();
59
60 async move {
61 Ok::<_, Infallible>(service_fn(move |_req| {
62 let middleware = middleware.clone();
63 let error_middleware = error_middleware.clone();
64 let app_locals = app_locals.clone();
65
66 async move {
67 Ok::<_, Infallible>(
68 run(_req, &middleware, &error_middleware, &app_locals).await,
69 )
70 }
71 }))
72 }
73 }));
74
75 info!("Listening on {}", addr);
76 server.await?;
77
78 Ok(())
79 }
80
81 pub fn set_locals(&mut self, locals: T) -> &mut Self {
82 self.locals = Some(locals);
83
84 self
85 }
86
87 pub fn router(&mut self, router: Router<T>) -> &mut Self {
88 self.routers.push(router);
89
90 self
91 }
92
93 pub fn use_ok<F>(&mut self, handler: F) -> &mut Self
95 where
96 F: Fn(&mut Request<T>, &mut Response, &mut NextFunction) + Send + Sync + 'static,
97 {
98 let router = self.routers.get_mut(0).unwrap();
99
100 router.use_ok(handler);
101
102 self
103 }
104
105 pub fn use_err<F>(&mut self, handler: F) -> &mut Self
107 where
108 F: Fn(&Error, &mut Request<T>, &mut Response, &mut NextFunction) + Send + Sync + 'static,
109 {
110 let router = self.routers.get_mut(0).unwrap();
111
112 router.use_err(handler);
113
114 self
115 }
116
117 pub fn get<F>(&mut self, path: &'static str, handler: F) -> &mut Self
119 where
120 F: Fn(&mut Request<T>, &mut Response, &mut NextFunction) + Send + Sync + 'static,
121 {
122 let router = self.routers.get_mut(0).unwrap();
123
124 router.get(path, handler);
125
126 self
127 }
128
129 pub fn post<F>(&mut self, path: &'static str, handler: F) -> &mut Self
131 where
132 F: Fn(&mut Request<T>, &mut Response, &mut NextFunction) + Send + Sync + 'static,
133 {
134 let router = self.routers.get_mut(0).unwrap();
135
136 router.post(path, handler);
137
138 self
139 }
140
141 pub fn put<F>(&mut self, path: &'static str, handler: F) -> &mut Self
143 where
144 F: Fn(&mut Request<T>, &mut Response, &mut NextFunction) + Send + Sync + 'static,
145 {
146 let router = self.routers.get_mut(0).unwrap();
147
148 router.put(path, handler);
149
150 self
151 }
152
153 pub fn patch<F>(&mut self, path: &'static str, handler: F) -> &mut Self
155 where
156 F: Fn(&mut Request<T>, &mut Response, &mut NextFunction) + Send + Sync + 'static,
157 {
158 let router = self.routers.get_mut(0).unwrap();
159
160 router.patch(path, handler);
161
162 self
163 }
164
165 pub fn delete<F>(&mut self, path: &'static str, handler: F) -> &mut Self
167 where
168 F: Fn(&mut Request<T>, &mut Response, &mut NextFunction) + Send + Sync + 'static,
169 {
170 let router = self.routers.get_mut(0).unwrap();
171
172 router.delete(path, handler);
173
174 self
175 }
176
177 pub fn options<F>(&mut self, path: &'static str, handler: F) -> &mut Self
179 where
180 F: Fn(&mut Request<T>, &mut Response, &mut NextFunction) + Send + Sync + 'static,
181 {
182 let router = self.routers.get_mut(0).unwrap();
183
184 router.options(path, handler);
185
186 self
187 }
188}