diff --git a/src/client/response.rs b/src/client/response.rs index 1dcd21c4..fcc06468 100644 --- a/src/client/response.rs +++ b/src/client/response.rs @@ -1,6 +1,5 @@ //! Client Responses use std::io::{self, Read}; -use std::num::FromPrimitive; use std::marker::PhantomData; use buffer::BufReader; @@ -13,7 +12,6 @@ use http::HttpReader::{SizedReader, ChunkedReader, EofReader}; use status; use version; use HttpResult; -use HttpError::HttpStatusError; /// A response for a client request to a remote server. pub struct Response { @@ -39,10 +37,7 @@ impl Response { let raw_status = head.subject; let headers = head.headers; - let status = match FromPrimitive::from_u16(raw_status.0) { - Some(status) => status, - None => return Err(HttpStatusError) - }; + let status = status::StatusCode::from_u16(raw_status.0); debug!("version={:?}, status={:?}", head.version, status); debug!("headers={:?}", headers); diff --git a/src/header/common/authorization.rs b/src/header/common/authorization.rs index 1dcc2b23..a8f54ea4 100644 --- a/src/header/common/authorization.rs +++ b/src/header/common/authorization.rs @@ -1,7 +1,7 @@ +use std::any::Any; use std::fmt; use std::str::{FromStr, from_utf8}; use std::ops::{Deref, DerefMut}; -use std::marker::Reflect; use serialize::base64::{ToBase64, FromBase64, Standard, Config, Newline}; use header::{Header, HeaderFormat}; @@ -23,7 +23,7 @@ impl DerefMut for Authorization { } } -impl Header for Authorization where ::Err: 'static { +impl Header for Authorization where ::Err: 'static { fn header_name() -> &'static str { "Authorization" } @@ -44,7 +44,7 @@ impl Header for Authorization where HeaderFormat for Authorization where ::Err: 'static { +impl HeaderFormat for Authorization where ::Err: 'static { fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { match Scheme::scheme(None::) { Some(scheme) => try!(write!(fmt, "{} ", scheme)), @@ -71,7 +71,7 @@ impl Scheme for String { } fn fmt_scheme(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self) + write!(f, "{}", self) } } diff --git a/src/header/internals/item.rs b/src/header/internals/item.rs index f6d11af0..bfdc9f0c 100644 --- a/src/header/internals/item.rs +++ b/src/header/internals/item.rs @@ -1,7 +1,10 @@ +use std::any::Any; use std::any::TypeId; use std::fmt; use std::str::from_utf8; +use typeable::Typeable; + use super::cell::{OptCell, PtrMapCell}; use header::{Header, HeaderFormat}; @@ -24,7 +27,7 @@ impl Item { #[inline] pub fn new_typed(ty: Box) -> Item { let map = PtrMapCell::new(); - unsafe { map.insert((&*ty).get_type_id(), ty); } + unsafe { map.insert((*ty).get_type(), ty); } Item { raw: OptCell::new(None), typed: map, @@ -51,7 +54,7 @@ impl Item { &raw[..] } - pub fn typed(&self) -> Option<&H> { + pub fn typed(&self) -> Option<&H> { let tid = TypeId::of::(); match self.typed.get(tid) { Some(val) => Some(val), diff --git a/src/header/mod.rs b/src/header/mod.rs index 7cbe0b0b..9ab28078 100644 --- a/src/header/mod.rs +++ b/src/header/mod.rs @@ -12,6 +12,7 @@ use std::iter::{FromIterator, IntoIterator}; use std::{mem, fmt}; use {httparse, traitobject}; +use typeable::Typeable; use unicase::UniCase; use self::internals::Item; @@ -50,7 +51,7 @@ pub trait Header: Clone + Any + Send + Sync { /// A trait for any object that will represent a header field and value. /// /// This trait represents the formatting of a Header for output to a TcpStream. -pub trait HeaderFormat: fmt::Debug + HeaderClone + Any + Send + Sync { +pub trait HeaderFormat: fmt::Debug + HeaderClone + Any + Typeable + Send + Sync { /// Format a header to be output into a TcpStream. /// /// This method is not allowed to introduce an Err not produced @@ -61,12 +62,12 @@ pub trait HeaderFormat: fmt::Debug + HeaderClone + Any + Send + Sync { #[doc(hidden)] pub trait HeaderClone { - fn clone_box(&self) -> Box; + fn clone_box(&self) -> Box; } -impl HeaderClone for T { +impl HeaderClone for T { #[inline] - fn clone_box(&self) -> Box { + fn clone_box(&self) -> Box { Box::new(self.clone()) } } diff --git a/src/header/shared/quality_item.rs b/src/header/shared/quality_item.rs index 59adf3e9..b8223ba7 100644 --- a/src/header/shared/quality_item.rs +++ b/src/header/shared/quality_item.rs @@ -6,7 +6,6 @@ use std::cmp; use std::default::Default; use std::fmt; -use std::num::{FromPrimitive, ToPrimitive}; use std::str; /// Represents a quality used in quality values. @@ -20,7 +19,7 @@ use std::str; /// floating point data type (`f32`) consumes four bytes, hyper uses an `u16` value to store the /// quality internally. For performance reasons you may set quality directly to a value between /// 0 and 1000 e.g. `Quality(532)` matches the quality `q=0.532`. -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] pub struct Quality(pub u16); impl fmt::Display for Quality { @@ -33,43 +32,6 @@ impl fmt::Display for Quality { } } -impl FromPrimitive for Quality { - fn from_i64(n: i64) -> Option { - match n >= 0 { - true => FromPrimitive::from_u64(n as u64), - false => None, - } - } - - fn from_u64(n: u64) -> Option { - match n <= 1000 { - true => Some(Quality(n as u16)), - false => None, - } - } - - fn from_f64(n: f64) -> Option { - match n >= 0f64 && n <= 1f64 { - true => Some(Quality((n * 1000f64) as u16)), - false => None, - } - } -} - -impl ToPrimitive for Quality { - fn to_i64(&self) -> Option { - Some(self.0 as i64) - } - - fn to_u64(&self) -> Option { - Some(self.0 as u64) - } - - fn to_f64(&self) -> Option { - Some((self.0 as f64) / 1000f64) - } -} - impl Default for Quality { fn default() -> Quality { Quality(1000) @@ -91,7 +53,10 @@ impl QualityItem { /// The item can be of any type. /// The quality should be a value in the range [0, 1]. pub fn new(item: T, quality: Quality) -> QualityItem { - QualityItem{item: item, quality: quality} + QualityItem { + item: item, + quality: quality + } } } @@ -136,12 +101,21 @@ impl str::FromStr for QualityItem { } } match raw_item.parse::() { - Ok(item) => Ok(QualityItem::new(item, FromPrimitive::from_f32(quality).unwrap())), + // we already checked above that the quality is within range + Ok(item) => Ok(QualityItem::new(item, from_f32(quality))), Err(_) => return Err(()), } } } +fn from_f32(f: f32) -> Quality { + // this function is only used internally. A check that `f` is within range + // should be done before calling this method. Just in case, this + // debug_assert should catch if we were forgetful + debug_assert!(f >= 0f32 && f <= 1f32, "q value must be between 0.0 and 1.0"); + Quality((f * 1000f32) as u16) +} + /// Convinience function to wrap a value in a `QualityItem` /// Sets `q` to the default 1.0 pub fn qitem(item: T) -> QualityItem { @@ -150,13 +124,12 @@ pub fn qitem(item: T) -> QualityItem { /// Convenience function to create a `Quality` fromt a float. pub fn q(f: f32) -> Quality { - FromPrimitive::from_f32(f).expect("q value must be between 0.0 and 1.0") + assert!(f >= 0f32 && f <= 1f32, "q value must be between 0.0 and 1.0"); + from_f32(f) } #[cfg(test)] mod tests { - use std::num::FromPrimitive; - use super::*; use super::super::encoding::*; @@ -206,25 +179,32 @@ mod tests { assert_eq!(x, Err(())); } #[test] + fn test_quality_item_from_str6() { + let x: Result, ()> = "gzip; q=2".parse(); + assert_eq!(x, Err(())); + } + #[test] fn test_quality_item_ordering() { let x: QualityItem = "gzip; q=0.5".parse().ok().unwrap(); let y: QualityItem = "gzip; q=0.273".parse().ok().unwrap(); let comparision_result: bool = x.gt(&y); assert_eq!(comparision_result, true) } + #[test] fn test_quality() { - assert_eq!(Some(Quality(421)), FromPrimitive::from_f64(0.421f64)); - assert_eq!(Some(Quality(421)), FromPrimitive::from_f32(0.421f32)); - assert_eq!(Some(Quality(421)), FromPrimitive::from_i16(421i16)); - assert_eq!(Some(Quality(421)), FromPrimitive::from_i32(421i32)); - assert_eq!(Some(Quality(421)), FromPrimitive::from_i64(421i64)); - assert_eq!(Some(Quality(421)), FromPrimitive::from_u16(421u16)); - assert_eq!(Some(Quality(421)), FromPrimitive::from_u32(421u32)); - assert_eq!(Some(Quality(421)), FromPrimitive::from_u64(421u64)); + assert_eq!(q(0.5), Quality(500)); + } - assert_eq!(None::, FromPrimitive::from_i16(-5i16)); - assert_eq!(None::, FromPrimitive::from_i32(5000i32)); - assert_eq!(None::, FromPrimitive::from_f32(2.5f32)); + #[test] + #[should_panic] + fn test_quality_invalid() { + q(-1.0); + } + + #[test] + #[should_panic] + fn test_quality_invalid2() { + q(2.0); } } diff --git a/src/http.rs b/src/http.rs index 1df35eb1..13b8104d 100644 --- a/src/http.rs +++ b/src/http.rs @@ -2,7 +2,6 @@ use std::borrow::{Cow, ToOwned}; use std::cmp::min; use std::io::{self, Read, Write, BufRead}; -use std::num::FromPrimitive; use httparse; @@ -378,11 +377,8 @@ impl<'a> TryParse for httparse::Response<'a> { Ok(match try!(res.parse(buf)) { httparse::Status::Complete(len) => { let code = res.code.unwrap(); - let reason = match ::from_u16(code) { - Some(status) => match status.canonical_reason() { - Some(reason) => Cow::Borrowed(reason), - None => Cow::Owned(res.reason.unwrap().to_owned()) - }, + let reason = match StatusCode::from_u16(code).canonical_reason() { + Some(reason) => Cow::Borrowed(reason), None => Cow::Owned(res.reason.unwrap().to_owned()) }; httparse::Status::Complete((Incoming { diff --git a/src/lib.rs b/src/lib.rs index 7f52e11f..20243f29 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,4 @@ #![doc(html_root_url = "https://hyperium.github.io/hyper/hyper/index.html")] -#![feature(core)] #![deny(missing_docs)] #![cfg_attr(test, deny(warnings))] #![cfg_attr(test, feature(test))] diff --git a/src/net.rs b/src/net.rs index d48cc69b..216f41d3 100644 --- a/src/net.rs +++ b/src/net.rs @@ -6,7 +6,6 @@ use std::net::{SocketAddr, ToSocketAddrs, TcpStream, TcpListener}; use std::mem; use std::path::Path; use std::sync::Arc; -use std::marker::Reflect; use openssl::ssl::{Ssl, SslStream, SslContext}; use openssl::ssl::SslVerifyMode::SslVerifyNone; @@ -135,7 +134,7 @@ impl NetworkStream + Send { /// If the underlying type is T, get a mutable reference to the contained /// data. #[inline] - pub fn downcast_mut(&mut self) -> Option<&mut T> { + pub fn downcast_mut(&mut self) -> Option<&mut T> { if self.is::() { Some(unsafe { self.downcast_mut_unchecked() }) } else { @@ -144,7 +143,7 @@ impl NetworkStream + Send { } /// If the underlying type is T, extract it. - pub fn downcast(self: Box) + pub fn downcast(self: Box) -> Result, Box> { if self.is::() { Ok(unsafe { self.downcast_unchecked() }) diff --git a/src/status.rs b/src/status.rs index 5a86e6f1..62c1d093 100644 --- a/src/status.rs +++ b/src/status.rs @@ -1,6 +1,5 @@ //! HTTP status codes use std::fmt; -use std::num::{FromPrimitive, ToPrimitive}; use std::cmp::Ordering; // shamelessly lifted from Teepee. I tried a few schemes, this really @@ -20,11 +19,9 @@ use std::cmp::Ordering; /// `self.class().default_code()`: /// /// ```rust -/// #![feature(core)] -/// # use std::num::FromPrimitive; /// # use hyper::status::StatusCode; -/// let statusopt: Option = FromPrimitive::from_u16(137u16); -/// assert_eq!(statusopt.unwrap().class().default_code(), StatusCode::Continue); +/// let status = StatusCode::Unregistered(123); +/// assert_eq!(status.class().default_code(), StatusCode::Continue); /// ``` /// /// IANA maintain the [Hypertext Transfer Protocol (HTTP) Status Code @@ -225,6 +222,136 @@ pub enum StatusCode { impl StatusCode { + #[doc(hidden)] + pub fn from_u16(n: u16) -> StatusCode { + match n { + 100 => StatusCode::Continue, + 101 => StatusCode::SwitchingProtocols, + 102 => StatusCode::Processing, + 200 => StatusCode::Ok, + 201 => StatusCode::Created, + 202 => StatusCode::Accepted, + 203 => StatusCode::NonAuthoritativeInformation, + 204 => StatusCode::NoContent, + 205 => StatusCode::ResetContent, + 206 => StatusCode::PartialContent, + 207 => StatusCode::MultiStatus, + 208 => StatusCode::AlreadyReported, + 226 => StatusCode::ImUsed, + 300 => StatusCode::MultipleChoices, + 301 => StatusCode::MovedPermanently, + 302 => StatusCode::Found, + 303 => StatusCode::SeeOther, + 304 => StatusCode::NotModified, + 305 => StatusCode::UseProxy, + 307 => StatusCode::TemporaryRedirect, + 308 => StatusCode::PermanentRedirect, + 400 => StatusCode::BadRequest, + 401 => StatusCode::Unauthorized, + 402 => StatusCode::PaymentRequired, + 403 => StatusCode::Forbidden, + 404 => StatusCode::NotFound, + 405 => StatusCode::MethodNotAllowed, + 406 => StatusCode::NotAcceptable, + 407 => StatusCode::ProxyAuthenticationRequired, + 408 => StatusCode::RequestTimeout, + 409 => StatusCode::Conflict, + 410 => StatusCode::Gone, + 411 => StatusCode::LengthRequired, + 412 => StatusCode::PreconditionFailed, + 413 => StatusCode::PayloadTooLarge, + 414 => StatusCode::UriTooLong, + 415 => StatusCode::UnsupportedMediaType, + 416 => StatusCode::RangeNotSatisfiable, + 417 => StatusCode::ExpectationFailed, + 418 => StatusCode::ImATeapot, + 422 => StatusCode::UnprocessableEntity, + 423 => StatusCode::Locked, + 424 => StatusCode::FailedDependency, + 426 => StatusCode::UpgradeRequired, + 428 => StatusCode::PreconditionRequired, + 429 => StatusCode::TooManyRequests, + 431 => StatusCode::RequestHeaderFieldsTooLarge, + 500 => StatusCode::InternalServerError, + 501 => StatusCode::NotImplemented, + 502 => StatusCode::BadGateway, + 503 => StatusCode::ServiceUnavailable, + 504 => StatusCode::GatewayTimeout, + 505 => StatusCode::HttpVersionNotSupported, + 506 => StatusCode::VariantAlsoNegotiates, + 507 => StatusCode::InsufficientStorage, + 508 => StatusCode::LoopDetected, + 510 => StatusCode::NotExtended, + 511 => StatusCode::NetworkAuthenticationRequired, + _ => StatusCode::Unregistered(n), + } + } + + #[doc(hidden)] + pub fn to_u16(&self) -> u16 { + match *self { + StatusCode::Continue => 100, + StatusCode::SwitchingProtocols => 101, + StatusCode::Processing => 102, + StatusCode::Ok => 200, + StatusCode::Created => 201, + StatusCode::Accepted => 202, + StatusCode::NonAuthoritativeInformation => 203, + StatusCode::NoContent => 204, + StatusCode::ResetContent => 205, + StatusCode::PartialContent => 206, + StatusCode::MultiStatus => 207, + StatusCode::AlreadyReported => 208, + StatusCode::ImUsed => 226, + StatusCode::MultipleChoices => 300, + StatusCode::MovedPermanently => 301, + StatusCode::Found => 302, + StatusCode::SeeOther => 303, + StatusCode::NotModified => 304, + StatusCode::UseProxy => 305, + StatusCode::TemporaryRedirect => 307, + StatusCode::PermanentRedirect => 308, + StatusCode::BadRequest => 400, + StatusCode::Unauthorized => 401, + StatusCode::PaymentRequired => 402, + StatusCode::Forbidden => 403, + StatusCode::NotFound => 404, + StatusCode::MethodNotAllowed => 405, + StatusCode::NotAcceptable => 406, + StatusCode::ProxyAuthenticationRequired => 407, + StatusCode::RequestTimeout => 408, + StatusCode::Conflict => 409, + StatusCode::Gone => 410, + StatusCode::LengthRequired => 411, + StatusCode::PreconditionFailed => 412, + StatusCode::PayloadTooLarge => 413, + StatusCode::UriTooLong => 414, + StatusCode::UnsupportedMediaType => 415, + StatusCode::RangeNotSatisfiable => 416, + StatusCode::ExpectationFailed => 417, + StatusCode::ImATeapot => 418, + StatusCode::UnprocessableEntity => 422, + StatusCode::Locked => 423, + StatusCode::FailedDependency => 424, + StatusCode::UpgradeRequired => 426, + StatusCode::PreconditionRequired => 428, + StatusCode::TooManyRequests => 429, + StatusCode::RequestHeaderFieldsTooLarge => 431, + StatusCode::InternalServerError => 500, + StatusCode::NotImplemented => 501, + StatusCode::BadGateway => 502, + StatusCode::ServiceUnavailable => 503, + StatusCode::GatewayTimeout => 504, + StatusCode::HttpVersionNotSupported => 505, + StatusCode::VariantAlsoNegotiates => 506, + StatusCode::InsufficientStorage => 507, + StatusCode::LoopDetected => 508, + StatusCode::NotExtended => 510, + StatusCode::NetworkAuthenticationRequired => 511, + StatusCode::Unregistered(n) => n, + } + } + /// Get the standardised `reason-phrase` for this status code. /// /// This is mostly here for servers writing responses, but could potentially have application @@ -312,7 +439,7 @@ impl StatusCode { /// Determine the class of a status code, based on its first digit. pub fn class(&self) -> StatusClass { - match self.to_u16().unwrap() { + match self.to_u16() { 100...199 => StatusClass::Informational, 200...299 => StatusClass::Success, 300...399 => StatusClass::Redirection, @@ -363,19 +490,9 @@ impl Copy for StatusCode {} /// assert_eq!(format!("{}", Unregistered(123)), /// "123 "); /// ``` -/// -/// If you wish to just include the number, convert to `u16` instead: -/// -/// ```rust -/// #![feature(core)] -/// # use std::num::ToPrimitive; -/// # use hyper::status::StatusCode::{ImATeapot, Unregistered}; -/// assert_eq!(format!("{}", ImATeapot.to_u16().unwrap()), "418"); -/// assert_eq!(format!("{}", Unregistered(123).to_u16().unwrap()), "123"); -/// ``` impl fmt::Display for StatusCode { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{} {}", self.to_u16().unwrap(), + write!(f, "{} {}", self.to_u16(), self.canonical_reason().unwrap_or("")) } } @@ -396,88 +513,10 @@ impl Clone for StatusCode { } } -impl FromPrimitive for StatusCode { - fn from_i64(n: i64) -> Option { - if n < 0 { - None - } else { - FromPrimitive::from_u64(n as u64) - } - } - - fn from_u64(n: u64) -> Option { - if n > 65535 { - None - } else { - Some(match n { - 100 => StatusCode::Continue, - 101 => StatusCode::SwitchingProtocols, - 102 => StatusCode::Processing, - 200 => StatusCode::Ok, - 201 => StatusCode::Created, - 202 => StatusCode::Accepted, - 203 => StatusCode::NonAuthoritativeInformation, - 204 => StatusCode::NoContent, - 205 => StatusCode::ResetContent, - 206 => StatusCode::PartialContent, - 207 => StatusCode::MultiStatus, - 208 => StatusCode::AlreadyReported, - 226 => StatusCode::ImUsed, - 300 => StatusCode::MultipleChoices, - 301 => StatusCode::MovedPermanently, - 302 => StatusCode::Found, - 303 => StatusCode::SeeOther, - 304 => StatusCode::NotModified, - 305 => StatusCode::UseProxy, - 307 => StatusCode::TemporaryRedirect, - 308 => StatusCode::PermanentRedirect, - 400 => StatusCode::BadRequest, - 401 => StatusCode::Unauthorized, - 402 => StatusCode::PaymentRequired, - 403 => StatusCode::Forbidden, - 404 => StatusCode::NotFound, - 405 => StatusCode::MethodNotAllowed, - 406 => StatusCode::NotAcceptable, - 407 => StatusCode::ProxyAuthenticationRequired, - 408 => StatusCode::RequestTimeout, - 409 => StatusCode::Conflict, - 410 => StatusCode::Gone, - 411 => StatusCode::LengthRequired, - 412 => StatusCode::PreconditionFailed, - 413 => StatusCode::PayloadTooLarge, - 414 => StatusCode::UriTooLong, - 415 => StatusCode::UnsupportedMediaType, - 416 => StatusCode::RangeNotSatisfiable, - 417 => StatusCode::ExpectationFailed, - 418 => StatusCode::ImATeapot, - 422 => StatusCode::UnprocessableEntity, - 423 => StatusCode::Locked, - 424 => StatusCode::FailedDependency, - 426 => StatusCode::UpgradeRequired, - 428 => StatusCode::PreconditionRequired, - 429 => StatusCode::TooManyRequests, - 431 => StatusCode::RequestHeaderFieldsTooLarge, - 500 => StatusCode::InternalServerError, - 501 => StatusCode::NotImplemented, - 502 => StatusCode::BadGateway, - 503 => StatusCode::ServiceUnavailable, - 504 => StatusCode::GatewayTimeout, - 505 => StatusCode::HttpVersionNotSupported, - 506 => StatusCode::VariantAlsoNegotiates, - 507 => StatusCode::InsufficientStorage, - 508 => StatusCode::LoopDetected, - 510 => StatusCode::NotExtended, - 511 => StatusCode::NetworkAuthenticationRequired, - _ => StatusCode::Unregistered(n as u16), - }) - } - } -} - impl PartialOrd for StatusCode { #[inline] fn partial_cmp(&self, other: &StatusCode) -> Option { - self.to_u16().unwrap().partial_cmp(&(other.to_u16().unwrap())) + self.to_u16().partial_cmp(&(other.to_u16())) } } @@ -494,76 +533,6 @@ impl Ord for StatusCode { } } -impl ToPrimitive for StatusCode { - fn to_i64(&self) -> Option { - Some(self.to_u64().unwrap() as i64) - } - - fn to_u64(&self) -> Option { - Some(match *self { - StatusCode::Continue => 100, - StatusCode::SwitchingProtocols => 101, - StatusCode::Processing => 102, - StatusCode::Ok => 200, - StatusCode::Created => 201, - StatusCode::Accepted => 202, - StatusCode::NonAuthoritativeInformation => 203, - StatusCode::NoContent => 204, - StatusCode::ResetContent => 205, - StatusCode::PartialContent => 206, - StatusCode::MultiStatus => 207, - StatusCode::AlreadyReported => 208, - StatusCode::ImUsed => 226, - StatusCode::MultipleChoices => 300, - StatusCode::MovedPermanently => 301, - StatusCode::Found => 302, - StatusCode::SeeOther => 303, - StatusCode::NotModified => 304, - StatusCode::UseProxy => 305, - StatusCode::TemporaryRedirect => 307, - StatusCode::PermanentRedirect => 308, - StatusCode::BadRequest => 400, - StatusCode::Unauthorized => 401, - StatusCode::PaymentRequired => 402, - StatusCode::Forbidden => 403, - StatusCode::NotFound => 404, - StatusCode::MethodNotAllowed => 405, - StatusCode::NotAcceptable => 406, - StatusCode::ProxyAuthenticationRequired => 407, - StatusCode::RequestTimeout => 408, - StatusCode::Conflict => 409, - StatusCode::Gone => 410, - StatusCode::LengthRequired => 411, - StatusCode::PreconditionFailed => 412, - StatusCode::PayloadTooLarge => 413, - StatusCode::UriTooLong => 414, - StatusCode::UnsupportedMediaType => 415, - StatusCode::RangeNotSatisfiable => 416, - StatusCode::ExpectationFailed => 417, - StatusCode::ImATeapot => 418, - StatusCode::UnprocessableEntity => 422, - StatusCode::Locked => 423, - StatusCode::FailedDependency => 424, - StatusCode::UpgradeRequired => 426, - StatusCode::PreconditionRequired => 428, - StatusCode::TooManyRequests => 429, - StatusCode::RequestHeaderFieldsTooLarge => 431, - StatusCode::InternalServerError => 500, - StatusCode::NotImplemented => 501, - StatusCode::BadGateway => 502, - StatusCode::ServiceUnavailable => 503, - StatusCode::GatewayTimeout => 504, - StatusCode::HttpVersionNotSupported => 505, - StatusCode::VariantAlsoNegotiates => 506, - StatusCode::InsufficientStorage => 507, - StatusCode::LoopDetected => 508, - StatusCode::NotExtended => 510, - StatusCode::NetworkAuthenticationRequired => 511, - StatusCode::Unregistered(n) => n, - } as u64) - } -} - /// The class of an HTTP `status-code`. /// /// [RFC 7231, section 6 (Response Status Codes)](https://tools.ietf.org/html/rfc7231#section-6): @@ -669,20 +638,3 @@ impl StatusClass { } } } - -impl ToPrimitive for StatusClass { - fn to_i64(&self) -> Option { - Some(self.to_u64().unwrap() as i64) - } - - fn to_u64(&self) -> Option { - Some(match *self { - StatusClass::Informational => 100, - StatusClass::Success => 200, - StatusClass::Redirection => 300, - StatusClass::ClientError => 400, - StatusClass::ServerError => 500, - StatusClass::NoClass => 200, - }) - } -} diff --git a/src/version.rs b/src/version.rs index 468c9c0a..af7aa8bc 100644 --- a/src/version.rs +++ b/src/version.rs @@ -7,7 +7,7 @@ use std::fmt; use self::HttpVersion::{Http09, Http10, Http11, Http20}; /// Represents a version of the HTTP spec. -#[derive(PartialEq, PartialOrd, Copy, Debug)] +#[derive(PartialEq, PartialOrd, Copy, Clone, Eq, Ord, Hash, Debug)] pub enum HttpVersion { /// `HTTP/0.9` Http09,