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<E> From<E> for Box<dyn HttpError>
60where
61 E: HttpError + 'static,
62{
63 fn from(err: E) -> Self {
64 Box::new(err)
65 }
66}