mini_http_test/
handler.rs

1use 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/// A handler that can be used by a [Server](crate::Server). If the handler
11/// returns an error, the error will be logged and a 500 response will be
12/// returned to the client.
13#[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
38/// Converts a value into a [Result](Result)<T, [Infallible](Infallible)> so it
39/// can be used as the return type for a Handler.
40///
41/// Useful for closures where you can't specify the return type and you don't
42/// need to return an error.
43pub 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}