1use std::fmt;
4
5pub type Result<T> = std::result::Result<T, Error>;
6
7#[derive(Debug)]
9pub enum Error {
10 BadRequest(String),
12 Unauthorized(String),
14 Forbidden(String),
16 NotFound(String),
18 Internal(String),
20 Custom(u16, String),
22}
23
24impl Error {
25 pub fn status_code(&self) -> u16 {
26 match self {
27 Error::BadRequest(_) => 400,
28 Error::Unauthorized(_) => 401,
29 Error::Forbidden(_) => 403,
30 Error::NotFound(_) => 404,
31 Error::Internal(_) => 500,
32 Error::Custom(code, _) => *code,
33 }
34 }
35
36 pub fn status(&self) -> http::StatusCode {
38 http::StatusCode::from_u16(self.status_code())
39 .unwrap_or(http::StatusCode::INTERNAL_SERVER_ERROR)
40 }
41
42 pub fn message(&self) -> &str {
43 match self {
44 Error::BadRequest(msg)
45 | Error::Unauthorized(msg)
46 | Error::Forbidden(msg)
47 | Error::NotFound(msg)
48 | Error::Internal(msg)
49 | Error::Custom(_, msg) => msg,
50 }
51 }
52}
53
54impl fmt::Display for Error {
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56 write!(f, "{}", self.message())
57 }
58}
59
60impl std::error::Error for Error {}
61
62impl Error {
64 pub fn bad_request(msg: impl Into<String>) -> Self {
65 Error::BadRequest(msg.into())
66 }
67
68 pub fn unauthorized(msg: impl Into<String>) -> Self {
69 Error::Unauthorized(msg.into())
70 }
71
72 pub fn forbidden(msg: impl Into<String>) -> Self {
73 Error::Forbidden(msg.into())
74 }
75
76 pub fn not_found(msg: impl Into<String>) -> Self {
77 Error::NotFound(msg.into())
78 }
79
80 pub fn internal(msg: impl Into<String>) -> Self {
81 Error::Internal(msg.into())
82 }
83
84 pub fn custom(status: u16, msg: impl Into<String>) -> Self {
85 Error::Custom(status, msg.into())
86 }
87}