1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
pub use anyhow::{Error, Result};

use crate::http::{Body, StatusCode};
use crate::response::{Responder, Response};

use futures::future::{self, Ready};

pub trait CatchExt {
    type Value;
    type Error;
    fn catch<E>(self) -> Result<Result<Self::Value, E>, Self::Error>
    where
        E: std::error::Error + Send + Sync + 'static;
}

impl<T> CatchExt for Result<T> {
    type Value = T;
    type Error = Error;

    fn catch<E>(self) -> Result<Result<Self::Value, E>, Self::Error>
    where
        E: std::error::Error + Send + Sync + 'static,
    {
        match self {
            Ok(value) => Ok(Ok(value)),
            Err(err) => match err.downcast::<E>() {
                Ok(e) => Ok(Err(e)),
                Err(err) => Err(err),
            },
        }
    }
}

#[derive(Debug, thiserror::Error)]
#[error("Not Found")]
pub struct NotFound;

impl From<NotFound> for Response {
    fn from(_: NotFound) -> Self {
        let status = StatusCode::NOT_FOUND;
        let body = Body::from("Not Found");
        Response::new(status, body)
    }
}

impl Responder for NotFound {
    type Future = Ready<Result<Response>>;

    fn respond(self) -> Self::Future {
        future::ready(Ok(self.into()))
    }
}