1use crate::error::{Error, Result};
4use crate::handler::{DynHandler, Handler, HandlerWithParams};
5use crate::middleware::{Middleware, Next};
6use crate::request::{Params, Request};
7use crate::response::Response;
8use crate::router::Router;
9use http_body_util::BodyExt;
10use hyper::server::conn::http1;
11use hyper::service::service_fn;
12use hyper_util::rt::TokioIo;
13use std::convert::Infallible;
14use std::net::SocketAddr;
15use std::sync::Arc;
16use tokio::net::TcpListener;
17
18pub struct App {
20 router: Router,
21 middlewares: Vec<Arc<dyn Middleware>>,
22}
23
24impl App {
25 pub fn new() -> Self {
26 Self {
27 router: Router::new(),
28 middlewares: Vec::new(),
29 }
30 }
31
32 pub fn get<H>(mut self, path: &str, handler: H) -> Self
34 where
35 H: Handler,
36 {
37 if let Err(e) = self
38 .router
39 .insert("GET", path, Arc::new(handler) as DynHandler)
40 {
41 panic!("Failed to register GET route {}: {}", path, e);
42 }
43 self
44 }
45
46 pub fn get_with_params<F, Fut>(mut self, path: &str, handler: F) -> Self
48 where
49 F: Fn(Params) -> Fut + Send + Sync + 'static,
50 Fut: std::future::Future<Output = Result<Response>> + Send + 'static,
51 {
52 if let Err(e) = self.router.insert(
53 "GET",
54 path,
55 Arc::new(HandlerWithParams::new(handler)) as DynHandler,
56 ) {
57 panic!("Failed to register GET route {}: {}", path, e);
58 }
59 self
60 }
61
62 pub fn post<H>(mut self, path: &str, handler: H) -> Self
64 where
65 H: Handler,
66 {
67 if let Err(e) = self
68 .router
69 .insert("POST", path, Arc::new(handler) as DynHandler)
70 {
71 panic!("Failed to register POST route {}: {}", path, e);
72 }
73 self
74 }
75
76 pub fn put<H>(mut self, path: &str, handler: H) -> Self
78 where
79 H: Handler,
80 {
81 if let Err(e) = self
82 .router
83 .insert("PUT", path, Arc::new(handler) as DynHandler)
84 {
85 panic!("Failed to register PUT route {}: {}", path, e);
86 }
87 self
88 }
89
90 pub fn delete<H>(mut self, path: &str, handler: H) -> Self
92 where
93 H: Handler,
94 {
95 if let Err(e) = self
96 .router
97 .insert("DELETE", path, Arc::new(handler) as DynHandler)
98 {
99 panic!("Failed to register DELETE route {}: {}", path, e);
100 }
101 self
102 }
103
104 pub fn patch<H>(mut self, path: &str, handler: H) -> Self
106 where
107 H: Handler,
108 {
109 if let Err(e) = self
110 .router
111 .insert("PATCH", path, Arc::new(handler) as DynHandler)
112 {
113 panic!("Failed to register PATCH route {}: {}", path, e);
114 }
115 self
116 }
117
118 pub fn middleware<M>(mut self, middleware: M) -> Self
120 where
121 M: Middleware,
122 {
123 self.middlewares.push(Arc::new(middleware));
124 self
125 }
126
127 pub async fn run(self, addr: &str) -> Result<()> {
129 let addr: SocketAddr = addr
130 .parse()
131 .map_err(|e| Error::internal(format!("Invalid address: {}", e)))?;
132
133 let listener = TcpListener::bind(addr)
134 .await
135 .map_err(|e| Error::internal(format!("Failed to bind: {}", e)))?;
136
137 println!("š ullun-api listening on http://{}", addr);
138
139 let router = Arc::new(self.router);
140 let middlewares = Arc::new(self.middlewares);
141
142 let shutdown = async {
144 tokio::signal::ctrl_c()
145 .await
146 .expect("Failed to install CTRL+C handler");
147 println!("\nš Shutting down gracefully...");
148 };
149
150 tokio::select! {
151 _ = shutdown => {
152 println!("ā
Server stopped");
153 Ok(())
154 }
155 result = Self::serve_loop(listener, router, middlewares) => result
156 }
157 }
158
159 async fn serve_loop(
160 listener: TcpListener,
161 router: Arc<Router>,
162 middlewares: Arc<Vec<Arc<dyn Middleware>>>,
163 ) -> Result<()> {
164 loop {
165 let (stream, _) = listener
166 .accept()
167 .await
168 .map_err(|e| Error::internal(format!("Failed to accept: {}", e)))?;
169
170 let io = TokioIo::new(stream);
171 let router = router.clone();
172 let middlewares = middlewares.clone();
173
174 tokio::task::spawn(async move {
175 if let Err(err) = http1::Builder::new()
176 .serve_connection(
177 io,
178 service_fn(|req| {
179 let router = router.clone();
180 let middlewares = middlewares.clone();
181 async move {
182 Ok::<_, Infallible>(handle_request(req, router, middlewares).await)
183 }
184 }),
185 )
186 .await
187 {
188 eprintln!("Error serving connection: {:?}", err);
189 }
190 });
191 }
192 }
193}
194
195impl Default for App {
196 fn default() -> Self {
197 Self::new()
198 }
199}
200
201async fn handle_request(
202 req: hyper::Request<hyper::body::Incoming>,
203 router: Arc<Router>,
204 middlewares: Arc<Vec<Arc<dyn Middleware>>>,
205) -> hyper::Response<http_body_util::Full<bytes::Bytes>> {
206 let method = req.method().to_string();
207 let path = req.uri().path().to_string();
208
209 let (parts, body) = req.into_parts();
211 let body_bytes = match body.collect().await {
212 Ok(collected) => collected.to_bytes(),
213 Err(_) => bytes::Bytes::new(),
214 };
215
216 let mut request = Request::new(parts.method, parts.uri, parts.headers, body_bytes);
217
218 let result = match router.match_route(&method, &path) {
220 Ok((handler, params)) => {
221 request.params = params;
222
223 if middlewares.is_empty() {
225 handler.call(request).await
226 } else {
227 let mut chain = middlewares.to_vec();
229
230 let final_handler = Arc::new(move |req: Request, _next: Next| {
232 let h = handler.clone();
233 async move { h.call(req).await }
234 });
235 chain.push(final_handler as Arc<dyn Middleware>);
236
237 let next = Next::new(Arc::new(chain));
238 next.run(request).await
239 }
240 }
241 Err(e) => Err(e),
242 };
243
244 let response = match result {
246 Ok(resp) => resp,
247 Err(err) => Response::from_error(err),
248 };
249
250 response.into_hyper()
251}