summaryrefslogtreecommitdiffstats
path: root/third_party/rust/http/src/error.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/http/src/error.rs')
-rw-r--r--third_party/rust/http/src/error.rs149
1 files changed, 149 insertions, 0 deletions
diff --git a/third_party/rust/http/src/error.rs b/third_party/rust/http/src/error.rs
new file mode 100644
index 0000000000..ba690841b6
--- /dev/null
+++ b/third_party/rust/http/src/error.rs
@@ -0,0 +1,149 @@
+use std::error;
+use std::fmt;
+use std::result;
+
+use crate::header;
+use crate::method;
+use crate::status;
+use crate::uri;
+
+/// A generic "error" for HTTP connections
+///
+/// This error type is less specific than the error returned from other
+/// functions in this crate, but all other errors can be converted to this
+/// error. Consumers of this crate can typically consume and work with this form
+/// of error for conversions with the `?` operator.
+pub struct Error {
+ inner: ErrorKind,
+}
+
+/// A `Result` typedef to use with the `http::Error` type
+pub type Result<T> = result::Result<T, Error>;
+
+enum ErrorKind {
+ StatusCode(status::InvalidStatusCode),
+ Method(method::InvalidMethod),
+ Uri(uri::InvalidUri),
+ UriParts(uri::InvalidUriParts),
+ HeaderName(header::InvalidHeaderName),
+ HeaderValue(header::InvalidHeaderValue),
+}
+
+impl fmt::Debug for Error {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_tuple("http::Error")
+ // Skip the noise of the ErrorKind enum
+ .field(&self.get_ref())
+ .finish()
+ }
+}
+
+impl fmt::Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt::Display::fmt(self.get_ref(), f)
+ }
+}
+
+impl Error {
+ /// Return true if the underlying error has the same type as T.
+ pub fn is<T: error::Error + 'static>(&self) -> bool {
+ self.get_ref().is::<T>()
+ }
+
+ /// Return a reference to the lower level, inner error.
+ pub fn get_ref(&self) -> &(dyn error::Error + 'static) {
+ use self::ErrorKind::*;
+
+ match self.inner {
+ StatusCode(ref e) => e,
+ Method(ref e) => e,
+ Uri(ref e) => e,
+ UriParts(ref e) => e,
+ HeaderName(ref e) => e,
+ HeaderValue(ref e) => e,
+ }
+ }
+}
+
+impl error::Error for Error {
+ // Return any available cause from the inner error. Note the inner error is
+ // not itself the cause.
+ fn source(&self) -> Option<&(dyn error::Error + 'static)> {
+ self.get_ref().source()
+ }
+}
+
+impl From<status::InvalidStatusCode> for Error {
+ fn from(err: status::InvalidStatusCode) -> Error {
+ Error {
+ inner: ErrorKind::StatusCode(err),
+ }
+ }
+}
+
+impl From<method::InvalidMethod> for Error {
+ fn from(err: method::InvalidMethod) -> Error {
+ Error {
+ inner: ErrorKind::Method(err),
+ }
+ }
+}
+
+impl From<uri::InvalidUri> for Error {
+ fn from(err: uri::InvalidUri) -> Error {
+ Error {
+ inner: ErrorKind::Uri(err),
+ }
+ }
+}
+
+impl From<uri::InvalidUriParts> for Error {
+ fn from(err: uri::InvalidUriParts) -> Error {
+ Error {
+ inner: ErrorKind::UriParts(err),
+ }
+ }
+}
+
+impl From<header::InvalidHeaderName> for Error {
+ fn from(err: header::InvalidHeaderName) -> Error {
+ Error {
+ inner: ErrorKind::HeaderName(err),
+ }
+ }
+}
+
+impl From<header::InvalidHeaderValue> for Error {
+ fn from(err: header::InvalidHeaderValue) -> Error {
+ Error {
+ inner: ErrorKind::HeaderValue(err),
+ }
+ }
+}
+
+impl From<std::convert::Infallible> for Error {
+ fn from(err: std::convert::Infallible) -> Error {
+ match err {}
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn inner_error_is_invalid_status_code() {
+ if let Err(e) = status::StatusCode::from_u16(6666) {
+ let err: Error = e.into();
+ let ie = err.get_ref();
+ assert!(!ie.is::<header::InvalidHeaderValue>());
+ assert!(ie.is::<status::InvalidStatusCode>());
+ ie.downcast_ref::<status::InvalidStatusCode>().unwrap();
+
+ assert!(!err.is::<header::InvalidHeaderValue>());
+ assert!(err.is::<status::InvalidStatusCode>());
+ } else {
+ panic!("Bad status allowed!");
+ }
+ }
+}