mini_http_test/
handler.rs1use std::{convert::Infallible, fmt::Display, future::Future, pin::Pin};
2
3use async_trait::async_trait;
4use http_body_util::Full;
5use hyper::{
6 body::{Bytes, Incoming as IncomingBody},
7 Request, Response,
8};
9
10#[async_trait]
14pub trait Handler {
15 type Error: Display;
16 async fn handle(self, req: Request<IncomingBody>)
17 -> Result<Response<Full<Bytes>>, Self::Error>;
18}
19
20impl<F, Fut, E> Handler for F
21where
22 F: FnOnce(Request<IncomingBody>) -> Fut,
23 Fut: Future<Output = Result<Response<Full<Bytes>>, E>> + Send + 'static,
24 E: Display,
25{
26 type Error = E;
27
28 fn handle<'async_trait>(
29 self,
30 req: Request<IncomingBody>,
31 ) -> Pin<
32 Box<dyn Future<Output = Result<Response<Full<Bytes>>, Self::Error>> + Send + 'async_trait>,
33 > {
34 Box::pin(self(req))
35 }
36}
37
38pub fn handle_ok<T>(val: T) -> Result<T, Infallible> {
44 Ok(val)
45}
46
47pub(crate) async fn run_handler<H: Handler>(
48 handler: H,
49 req: Request<IncomingBody>,
50) -> Result<Response<Full<Bytes>>, Infallible> {
51 match handler.handle(req).await {
52 Ok(resp) => Ok(resp),
53 Err(err) => {
54 eprintln!("Error while handling request: {}", err);
55 Ok(Response::builder()
56 .status(500)
57 .body(Full::from(Bytes::from_static(b"Internal Server Error")))
58 .expect("should be a valid response"))
59 }
60 }
61}