1use crate::response::Response;
2use thiserror::Error as ThisError;
3
4#[derive(Debug, ThisError)]
6pub enum Error {
7 #[error("not found")]
8 NotFound,
9
10 #[error("unauthorized")]
11 Unauthorized,
12
13 #[error("bad request: {0}")]
14 BadRequest(String),
15
16 #[error("payload too large")]
17 PayloadTooLarge,
18
19 #[error("method not allowed")]
20 MethodNotAllowed,
21
22 #[error("internal error: {0}")]
23 Internal(String),
24
25 #[error("json error: {0}")]
26 Json(#[from] serde_json::Error),
27
28 #[error("io error: {0}")]
29 Io(#[from] std::io::Error),
30
31 #[error("response")]
33 Response(Box<Response>),
34}
35
36pub type Result<T> = std::result::Result<T, Error>;
37
38impl Error {
39 pub fn bad_request(msg: impl Into<String>) -> Self {
41 Self::BadRequest(msg.into())
42 }
43
44 pub fn custom(status: u16, body: impl IntoResponse) -> Self {
46 Error::Response(Box::new(body.into_response().status(status)))
47 }
48
49 pub fn into_response(self) -> Response {
50 match self {
51 Error::NotFound => Response::text("Not Found").status(404),
52 Error::Unauthorized => Response::text("Unauthorized").status(401),
53 Error::BadRequest(msg) => Response::text(msg).status(400),
54 Error::PayloadTooLarge => Response::text("Payload Too Large").status(413),
55 Error::MethodNotAllowed => Response::text("Method Not Allowed").status(405),
56 Error::Internal(msg) => Response::text(msg).status(500),
57 Error::Json(err) => Response::text(format!("JSON error: {err}")).status(400),
58 Error::Io(err) => Response::text(format!("IO error: {err}")).status(500),
59 Error::Response(res) => *res,
60 }
61 }
62}
63
64pub trait IntoResponse {
66 fn into_response(self) -> Response;
67}
68
69impl IntoResponse for Response {
70 fn into_response(self) -> Response {
71 self
72 }
73}
74
75impl IntoResponse for Error {
76 fn into_response(self) -> Response {
77 Error::into_response(self)
78 }
79}
80
81impl IntoResponse for String {
82 fn into_response(self) -> Response {
83 Response::text(self)
84 }
85}
86
87impl IntoResponse for &str {
88 fn into_response(self) -> Response {
89 Response::text(self)
90 }
91}