Skip to main content

rama_http_types/
error.rs

1//! HTTP-stack error type.
2//!
3//! Forked from the `http` crate's `Error`, adapted so the URI variant carries
4//! rama's native [`rama_net::uri::ParseError`] instead of `http::uri::InvalidUri`
5//! (the native [`Uri`](rama_net::uri::Uri) replaces the `http` crate's URI type).
6
7use std::error;
8use std::fmt;
9use std::result;
10
11use crate::header::MaxSizeReached;
12use crate::{header, method, status};
13
14/// A generic "error" for HTTP connections.
15///
16/// This error type is less specific than the error returned from other
17/// functions in this crate, but all other errors can be converted to this
18/// error. Consumers of this crate can typically consume and work with this form
19/// of error for conversions with the `?` operator.
20pub struct Error {
21    inner: ErrorKind,
22}
23
24/// A `Result` typedef to use with the [`Error`] type.
25pub type Result<T> = result::Result<T, Error>;
26
27enum ErrorKind {
28    StatusCode(status::InvalidStatusCode),
29    Method(method::InvalidMethod),
30    Version(rama_net::http::InvalidVersion),
31    Uri(rama_net::uri::ParseError),
32    HeaderName(header::InvalidHeaderName),
33    HeaderValue(header::InvalidHeaderValue),
34    MaxSizeReached(MaxSizeReached),
35}
36
37impl fmt::Debug for Error {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        f.debug_tuple("rama_http_types::Error")
40            // Skip the noise of the ErrorKind enum
41            .field(&self.get_ref())
42            .finish()
43    }
44}
45
46impl fmt::Display for Error {
47    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48        fmt::Display::fmt(self.get_ref(), f)
49    }
50}
51
52impl Error {
53    /// Return true if the underlying error has the same type as `T`.
54    pub fn is<T: error::Error + 'static>(&self) -> bool {
55        self.get_ref().is::<T>()
56    }
57
58    /// Return a reference to the lower level, inner error.
59    pub fn get_ref(&self) -> &(dyn error::Error + 'static) {
60        match self.inner {
61            ErrorKind::StatusCode(ref e) => e,
62            ErrorKind::Method(ref e) => e,
63            ErrorKind::Version(ref e) => e,
64            ErrorKind::Uri(ref e) => e,
65            ErrorKind::HeaderName(ref e) => e,
66            ErrorKind::HeaderValue(ref e) => e,
67            ErrorKind::MaxSizeReached(ref e) => e,
68        }
69    }
70}
71
72impl error::Error for Error {
73    // Return any available cause from the inner error. Note the inner error is
74    // not itself the cause.
75    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
76        self.get_ref().source()
77    }
78}
79
80impl From<status::InvalidStatusCode> for Error {
81    fn from(err: status::InvalidStatusCode) -> Self {
82        Self {
83            inner: ErrorKind::StatusCode(err),
84        }
85    }
86}
87
88impl From<method::InvalidMethod> for Error {
89    fn from(err: method::InvalidMethod) -> Self {
90        Self {
91            inner: ErrorKind::Method(err),
92        }
93    }
94}
95
96impl From<rama_net::http::InvalidVersion> for Error {
97    fn from(err: rama_net::http::InvalidVersion) -> Self {
98        Self {
99            inner: ErrorKind::Version(err),
100        }
101    }
102}
103
104impl From<rama_net::uri::ParseError> for Error {
105    fn from(err: rama_net::uri::ParseError) -> Self {
106        Self {
107            inner: ErrorKind::Uri(err),
108        }
109    }
110}
111
112impl From<header::InvalidHeaderName> for Error {
113    fn from(err: header::InvalidHeaderName) -> Self {
114        Self {
115            inner: ErrorKind::HeaderName(err),
116        }
117    }
118}
119
120impl From<header::InvalidHeaderValue> for Error {
121    fn from(err: header::InvalidHeaderValue) -> Self {
122        Self {
123            inner: ErrorKind::HeaderValue(err),
124        }
125    }
126}
127
128impl From<MaxSizeReached> for Error {
129    fn from(err: MaxSizeReached) -> Self {
130        Self {
131            inner: ErrorKind::MaxSizeReached(err),
132        }
133    }
134}
135
136impl From<std::convert::Infallible> for Error {
137    fn from(err: std::convert::Infallible) -> Self {
138        match err {}
139    }
140}