/rust/registry/src/index.crates.io-1949cf8c6b5b557f/http-1.5.0/src/error.rs
Line | Count | Source |
1 | | use std::error; |
2 | | use std::fmt; |
3 | | use std::result; |
4 | | |
5 | | use crate::header; |
6 | | use crate::header::MaxSizeReached; |
7 | | use crate::method; |
8 | | use crate::status; |
9 | | use crate::uri; |
10 | | |
11 | | /// A generic "error" for HTTP connections |
12 | | /// |
13 | | /// This error type is less specific than the error returned from other |
14 | | /// functions in this crate, but all other errors can be converted to this |
15 | | /// error. Consumers of this crate can typically consume and work with this form |
16 | | /// of error for conversions with the `?` operator. |
17 | | pub struct Error { |
18 | | inner: ErrorKind, |
19 | | } |
20 | | |
21 | | /// A `Result` typedef to use with the `http::Error` type |
22 | | pub type Result<T> = result::Result<T, Error>; |
23 | | |
24 | | enum ErrorKind { |
25 | | StatusCode(status::InvalidStatusCode), |
26 | | Method(method::InvalidMethod), |
27 | | Uri(uri::InvalidUri), |
28 | | UriParts(uri::InvalidUriParts), |
29 | | HeaderName(header::InvalidHeaderName), |
30 | | HeaderValue(header::InvalidHeaderValue), |
31 | | MaxSizeReached(MaxSizeReached), |
32 | | } |
33 | | |
34 | | impl fmt::Debug for Error { |
35 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
36 | 0 | f.debug_tuple("http::Error") |
37 | 0 | // Skip the noise of the ErrorKind enum |
38 | 0 | .field(&self.get_ref()) |
39 | 0 | .finish() |
40 | 0 | } |
41 | | } |
42 | | |
43 | | impl fmt::Display for Error { |
44 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
45 | 0 | fmt::Display::fmt(self.get_ref(), f) |
46 | 0 | } |
47 | | } |
48 | | |
49 | | impl Error { |
50 | 0 | pub(crate) fn is_empty_uri(&self) -> bool { |
51 | 0 | match self.inner { |
52 | 0 | ErrorKind::Uri(ref err) => err.is_empty(), |
53 | 0 | _ => false, |
54 | | } |
55 | 0 | } |
56 | | |
57 | | /// Return true if the underlying error has the same type as T. |
58 | 0 | pub fn is<T: error::Error + 'static>(&self) -> bool { |
59 | 0 | self.get_ref().is::<T>() |
60 | 0 | } |
61 | | |
62 | | /// Return a reference to the lower level, inner error. |
63 | 0 | pub fn get_ref(&self) -> &(dyn error::Error + 'static) { |
64 | | use self::ErrorKind::*; |
65 | | |
66 | 0 | match self.inner { |
67 | 0 | StatusCode(ref e) => e, |
68 | 0 | Method(ref e) => e, |
69 | 0 | Uri(ref e) => e, |
70 | 0 | UriParts(ref e) => e, |
71 | 0 | HeaderName(ref e) => e, |
72 | 0 | HeaderValue(ref e) => e, |
73 | 0 | MaxSizeReached(ref e) => e, |
74 | | } |
75 | 0 | } |
76 | | } |
77 | | |
78 | | impl error::Error for Error { |
79 | | // Return any available cause from the inner error. Note the inner error is |
80 | | // not itself the cause. |
81 | 0 | fn source(&self) -> Option<&(dyn error::Error + 'static)> { |
82 | 0 | self.get_ref().source() |
83 | 0 | } |
84 | | } |
85 | | |
86 | | impl From<MaxSizeReached> for Error { |
87 | 0 | fn from(err: MaxSizeReached) -> Error { |
88 | 0 | Error { |
89 | 0 | inner: ErrorKind::MaxSizeReached(err), |
90 | 0 | } |
91 | 0 | } |
92 | | } |
93 | | |
94 | | impl From<status::InvalidStatusCode> for Error { |
95 | 0 | fn from(err: status::InvalidStatusCode) -> Error { |
96 | 0 | Error { |
97 | 0 | inner: ErrorKind::StatusCode(err), |
98 | 0 | } |
99 | 0 | } |
100 | | } |
101 | | |
102 | | impl From<method::InvalidMethod> for Error { |
103 | 0 | fn from(err: method::InvalidMethod) -> Error { |
104 | 0 | Error { |
105 | 0 | inner: ErrorKind::Method(err), |
106 | 0 | } |
107 | 0 | } |
108 | | } |
109 | | |
110 | | impl From<uri::InvalidUri> for Error { |
111 | 0 | fn from(err: uri::InvalidUri) -> Error { |
112 | 0 | Error { |
113 | 0 | inner: ErrorKind::Uri(err), |
114 | 0 | } |
115 | 0 | } |
116 | | } |
117 | | |
118 | | impl From<uri::InvalidUriParts> for Error { |
119 | 0 | fn from(err: uri::InvalidUriParts) -> Error { |
120 | 0 | Error { |
121 | 0 | inner: ErrorKind::UriParts(err), |
122 | 0 | } |
123 | 0 | } |
124 | | } |
125 | | |
126 | | impl From<header::InvalidHeaderName> for Error { |
127 | 0 | fn from(err: header::InvalidHeaderName) -> Error { |
128 | 0 | Error { |
129 | 0 | inner: ErrorKind::HeaderName(err), |
130 | 0 | } |
131 | 0 | } |
132 | | } |
133 | | |
134 | | impl From<header::InvalidHeaderValue> for Error { |
135 | 0 | fn from(err: header::InvalidHeaderValue) -> Error { |
136 | 0 | Error { |
137 | 0 | inner: ErrorKind::HeaderValue(err), |
138 | 0 | } |
139 | 0 | } |
140 | | } |
141 | | |
142 | | impl From<std::convert::Infallible> for Error { |
143 | | fn from(err: std::convert::Infallible) -> Error { |
144 | | match err {} |
145 | | } |
146 | | } |
147 | | |
148 | | #[cfg(test)] |
149 | | mod tests { |
150 | | use super::*; |
151 | | |
152 | | #[test] |
153 | | fn inner_error_is_invalid_status_code() { |
154 | | if let Err(e) = status::StatusCode::from_u16(6666) { |
155 | | let err: Error = e.into(); |
156 | | let ie = err.get_ref(); |
157 | | assert!(!ie.is::<header::InvalidHeaderValue>()); |
158 | | assert!(ie.is::<status::InvalidStatusCode>()); |
159 | | ie.downcast_ref::<status::InvalidStatusCode>().unwrap(); |
160 | | |
161 | | assert!(!err.is::<header::InvalidHeaderValue>()); |
162 | | assert!(err.is::<status::InvalidStatusCode>()); |
163 | | } else { |
164 | | panic!("Bad status allowed!"); |
165 | | } |
166 | | } |
167 | | } |