http_error/
lib.rs

1mod any_http_error;
2pub mod error;
3pub mod option_ext;
4mod reason;
5pub mod result_ext;
6
7use std::error::Error;
8use std::fmt;
9
10pub use any_http_error::AnyHttpError;
11pub use http::StatusCode;
12use http::{HeaderName, HeaderValue};
13pub use option_ext::OptionExt;
14pub use reason::Reason;
15pub use result_ext::ResultExt;
16
17pub trait HttpError: Error {
18    fn status_code(&self) -> StatusCode;
19
20    fn reason(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21        if let Some(reason) = self.status_code().canonical_reason() {
22            f.write_str(reason)?;
23        }
24        Ok(())
25    }
26
27    fn headers(&self) -> Option<Vec<(HeaderName, HeaderValue)>> {
28        None
29    }
30
31    #[cfg(feature = "tracing")]
32    fn span(&self) -> Option<&tracing::Span> {
33        None
34    }
35}
36
37impl<E> HttpError for Box<E>
38where
39    E: HttpError,
40{
41    fn status_code(&self) -> StatusCode {
42        HttpError::status_code(&**self)
43    }
44
45    fn reason(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46        HttpError::reason(&**self, f)
47    }
48
49    fn headers(&self) -> Option<Vec<(HeaderName, HeaderValue)>> {
50        HttpError::headers(&**self)
51    }
52
53    #[cfg(feature = "tracing")]
54    fn span(&self) -> Option<&tracing::Span> {
55        HttpError::span(&**self)
56    }
57}
58
59impl HttpError for &dyn HttpError {
60    fn status_code(&self) -> StatusCode {
61        HttpError::status_code(&**self)
62    }
63
64    fn reason(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65        HttpError::reason(&**self, f)
66    }
67
68    fn headers(&self) -> Option<Vec<(HeaderName, HeaderValue)>> {
69        HttpError::headers(&**self)
70    }
71
72    #[cfg(feature = "tracing")]
73    fn span(&self) -> Option<&tracing::Span> {
74        HttpError::span(&**self)
75    }
76}
77
78impl<E> From<E> for Box<dyn HttpError>
79where
80    E: HttpError + 'static,
81{
82    fn from(err: E) -> Self {
83        Box::new(err)
84    }
85}