From ccd4814e69afabf84173cafa662ba8e1a1b0eb2a Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Mon, 30 Mar 2015 11:03:11 -0700 Subject: [PATCH] chore(stability): remove into_cow feature gate --- src/header/mod.rs | 28 ++++++++-------- src/http.rs | 24 +++++++------- src/lib.rs | 2 +- src/status.rs | 83 ++--------------------------------------------- 4 files changed, 29 insertions(+), 108 deletions(-) diff --git a/src/header/mod.rs b/src/header/mod.rs index 1f694795..687a60b7 100644 --- a/src/header/mod.rs +++ b/src/header/mod.rs @@ -5,14 +5,12 @@ //! must implement the `Header` trait from this module. Several common headers //! are already provided, such as `Host`, `ContentType`, `UserAgent`, and others. use std::any::Any; -use std::borrow::Cow::{Borrowed}; -use std::borrow::ToOwned; +use std::borrow::{Cow, ToOwned}; use std::fmt; -use std::raw::TraitObject; use std::collections::HashMap; use std::collections::hash_map::{Iter, Entry}; use std::iter::{FromIterator, IntoIterator}; -use std::borrow::{Cow, IntoCow}; +use std::raw::TraitObject; use std::{mem, raw}; use httparse; @@ -120,7 +118,7 @@ impl Headers { let mut headers = Headers::new(); for header in raw { debug!("raw header: {:?}={:?}", header.name, &header.value[..]); - let name = UniCase(header.name.to_owned().into_cow()); + let name = UniCase(Cow::Owned(header.name.to_owned())); let mut item = match headers.data.entry(name) { Entry::Vacant(entry) => entry.insert(Item::new_raw(vec![])), Entry::Occupied(entry) => entry.into_mut() @@ -136,7 +134,7 @@ impl Headers { /// /// The field is determined by the type of the value being set. pub fn set(&mut self, value: H) { - self.data.insert(UniCase(Borrowed(header_name::())), + self.data.insert(UniCase(Cow::Borrowed(header_name::())), Item::new_typed(Box::new(value))); } @@ -153,7 +151,7 @@ impl Headers { /// ``` pub fn get_raw(&self, name: &str) -> Option<&[Vec]> { self.data - .get(&UniCase(Borrowed(unsafe { mem::transmute::<&str, &str>(name) }))) + .get(&UniCase(Cow::Borrowed(unsafe { mem::transmute::<&str, &str>(name) }))) .map(Item::raw) } @@ -166,23 +164,23 @@ impl Headers { /// # let mut headers = Headers::new(); /// headers.set_raw("content-length", vec![b"5".to_vec()]); /// ``` - pub fn set_raw>(&mut self, name: K, value: Vec>) { - self.data.insert(UniCase(name.into_cow()), Item::new_raw(value)); + pub fn set_raw>>(&mut self, name: K, value: Vec>) { + self.data.insert(UniCase(name.into()), Item::new_raw(value)); } /// Remove a header set by set_raw pub fn remove_raw(&mut self, name: &str) { - self.data.remove(&UniCase(name.into_cow())); + self.data.remove(&UniCase(Cow::Borrowed(name))); } /// Get a reference to the header field's value, if it exists. pub fn get(&self) -> Option<&H> { - self.data.get(&UniCase(Borrowed(header_name::()))).and_then(Item::typed::) + self.data.get(&UniCase(Cow::Borrowed(header_name::()))).and_then(Item::typed::) } /// Get a mutable reference to the header field's value, if it exists. pub fn get_mut(&mut self) -> Option<&mut H> { - self.data.get_mut(&UniCase(Borrowed(header_name::()))).and_then(Item::typed_mut::) + self.data.get_mut(&UniCase(Cow::Borrowed(header_name::()))).and_then(Item::typed_mut::) } /// Returns a boolean of whether a certain header is in the map. @@ -196,13 +194,13 @@ impl Headers { /// let has_type = headers.has::(); /// ``` pub fn has(&self) -> bool { - self.data.contains_key(&UniCase(Borrowed(header_name::()))) + self.data.contains_key(&UniCase(Cow::Borrowed(header_name::()))) } /// Removes a header from the map, if one existed. /// Returns true if a header has been removed. pub fn remove(&mut self) -> bool { - self.data.remove(&UniCase(Borrowed(header_name::()))).is_some() + self.data.remove(&UniCase(Cow::Borrowed(header_name::()))).is_some() } /// Returns an iterator over the header fields. @@ -266,7 +264,7 @@ impl<'a> HeaderView<'a> { /// Check if a HeaderView is a certain Header. #[inline] pub fn is(&self) -> bool { - UniCase(header_name::().into_cow()) == *self.0 + UniCase(Cow::Borrowed(header_name::())) == *self.0 } /// Get the Header name as a slice. diff --git a/src/http.rs b/src/http.rs index b541e946..1df35eb1 100644 --- a/src/http.rs +++ b/src/http.rs @@ -1,13 +1,15 @@ //! Pieces pertaining to the HTTP message protocol. -use std::borrow::{Cow, IntoCow, ToOwned}; +use std::borrow::{Cow, ToOwned}; use std::cmp::min; use std::io::{self, Read, Write, BufRead}; +use std::num::FromPrimitive; use httparse; use buffer::BufReader; use header::Headers; use method::Method; +use status::StatusCode; use uri::RequestUri; use version::HttpVersion::{self, Http10, Http11}; use HttpError:: HttpTooLargeError; @@ -375,11 +377,17 @@ impl<'a> TryParse for httparse::Response<'a> { let mut res = httparse::Response::new(headers); 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()) + }, + None => Cow::Owned(res.reason.unwrap().to_owned()) + }; httparse::Status::Complete((Incoming { version: if res.version.unwrap() == 1 { Http11 } else { Http10 }, - subject: RawStatus( - res.code.unwrap(), res.reason.unwrap().to_owned().into_cow() - ), + subject: RawStatus(code, reason), headers: try!(Headers::from_raw(res.headers)) }, len)) }, @@ -405,15 +413,9 @@ pub const STAR: u8 = b'*'; pub const LINE_ENDING: &'static str = "\r\n"; /// The raw status code and reason-phrase. -#[derive(PartialEq, Debug)] +#[derive(Clone, PartialEq, Debug)] pub struct RawStatus(pub u16, pub Cow<'static, str>); -impl Clone for RawStatus { - fn clone(&self) -> RawStatus { - RawStatus(self.0, self.1.clone().into_cow()) - } -} - #[cfg(test)] mod tests { use std::io::{self, Write}; diff --git a/src/lib.rs b/src/lib.rs index 39cee212..e322a447 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,5 @@ #![doc(html_root_url = "https://hyperium.github.io/hyper/hyper/index.html")] -#![feature(core, into_cow)] +#![feature(core)] #![deny(missing_docs)] #![cfg_attr(test, deny(warnings))] #![cfg_attr(test, feature(test))] diff --git a/src/status.rs b/src/status.rs index d91a0502..5a86e6f1 100644 --- a/src/status.rs +++ b/src/status.rs @@ -31,6 +31,7 @@ use std::cmp::Ordering; /// Registry](http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml) which is /// the source for this enum (with one exception, 418 I'm a teapot, which is /// inexplicably not in the register). +#[derive(Debug)] pub enum StatusCode { /// 100 Continue /// [[RFC7231, Section 6.2.1](https://tools.ietf.org/html/rfc7231#section-6.2.1)] @@ -305,7 +306,7 @@ impl StatusCode { StatusCode::NotExtended => Some("Not Extended"), StatusCode::NetworkAuthenticationRequired => Some("Network Authentication Required"), - _ => None + StatusCode::Unregistered(..) => None } } @@ -379,86 +380,6 @@ impl fmt::Display for StatusCode { } } -impl fmt::Debug for StatusCode { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let s = match *self { - StatusCode::Continue => "Continue", - StatusCode::SwitchingProtocols => "SwitchingProtocols", - StatusCode::Processing => "Processing", - - StatusCode::Ok => "Ok", - StatusCode::Created => "Created", - StatusCode::Accepted => "Accepted", - StatusCode::NonAuthoritativeInformation => "NonAuthoritativeInformation", - StatusCode::NoContent => "NoContent", - StatusCode::ResetContent => "ResetContent", - StatusCode::PartialContent => "PartialContent", - StatusCode::MultiStatus => "MultiStatus", - StatusCode::AlreadyReported => "AlreadyReported", - - StatusCode::ImUsed => "ImUsed", - - StatusCode::MultipleChoices => "MultipleChoices", - StatusCode::MovedPermanently => "MovedPermanently", - StatusCode::Found => "Found", - StatusCode::SeeOther => "SeeOther", - StatusCode::NotModified => "NotModified", - StatusCode::UseProxy => "UseProxy", - - StatusCode::TemporaryRedirect => "TemporaryRedirect", - StatusCode::PermanentRedirect => "PermanentRedirect", - - StatusCode::BadRequest => "BadRequest", - StatusCode::Unauthorized => "Unauthorized", - StatusCode::PaymentRequired => "PaymentRequired", - StatusCode::Forbidden => "Forbidden", - StatusCode::NotFound => "NotFound", - StatusCode::MethodNotAllowed => "MethodNotAllowed", - StatusCode::NotAcceptable => "NotAcceptable", - StatusCode::ProxyAuthenticationRequired => "ProxyAuthenticationRequired", - StatusCode::RequestTimeout => "RequestTimeout", - StatusCode::Conflict => "Conflict", - StatusCode::Gone => "Gone", - StatusCode::LengthRequired => "LengthRequired", - StatusCode::PreconditionFailed => "PreconditionFailed", - StatusCode::PayloadTooLarge => "PayloadTooLarge", - StatusCode::UriTooLong => "UriTooLong", - StatusCode::UnsupportedMediaType => "UnsupportedMediaType", - StatusCode::RangeNotSatisfiable => "RangeNotSatisfiable", - StatusCode::ExpectationFailed => "ExpectationFailed", - StatusCode::ImATeapot => "ImATeapot", - - StatusCode::UnprocessableEntity => "UnprocessableEntity", - StatusCode::Locked => "Locked", - StatusCode::FailedDependency => "FailedDependency", - - StatusCode::UpgradeRequired => "UpgradeRequired", - - StatusCode::PreconditionRequired => "PreconditionRequired", - StatusCode::TooManyRequests => "TooManyRequests", - - StatusCode::RequestHeaderFieldsTooLarge => "RequestHeaderFieldsTooLarge", - - StatusCode::InternalServerError => "InternalServerError", - StatusCode::NotImplemented => "NotImplemented", - StatusCode::BadGateway => "BadGateway", - StatusCode::ServiceUnavailable => "ServiceUnavailable", - StatusCode::GatewayTimeout => "GatewayTimeout", - StatusCode::HttpVersionNotSupported => "HttpVersionNotSupported", - StatusCode::VariantAlsoNegotiates => "VariantAlsoNegotiates", - StatusCode::InsufficientStorage => "InsufficientStorage", - StatusCode::LoopDetected => "LoopDetected", - - StatusCode::NotExtended => "NotExtended", - StatusCode::NetworkAuthenticationRequired => "NetworkAuthenticationRequired", - StatusCode::Unregistered(ref code) => { - return write!(f, "Unregistered({})", code); - } - }; - f.write_str(s) - } -} - impl PartialEq for StatusCode { #[inline] fn eq(&self, other: &StatusCode) -> bool {