chore(stability): remove into_cow feature gate

This commit is contained in:
Sean McArthur
2015-03-30 11:03:11 -07:00
parent 1b28515b6e
commit ccd4814e69
4 changed files with 29 additions and 108 deletions

View File

@@ -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<H: Header + HeaderFormat>(&mut self, value: H) {
self.data.insert(UniCase(Borrowed(header_name::<H>())),
self.data.insert(UniCase(Cow::Borrowed(header_name::<H>())),
Item::new_typed(Box::new(value)));
}
@@ -153,7 +151,7 @@ impl Headers {
/// ```
pub fn get_raw(&self, name: &str) -> Option<&[Vec<u8>]> {
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<K: IntoCow<'static, str>>(&mut self, name: K, value: Vec<Vec<u8>>) {
self.data.insert(UniCase(name.into_cow()), Item::new_raw(value));
pub fn set_raw<K: Into<Cow<'static, str>>>(&mut self, name: K, value: Vec<Vec<u8>>) {
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<H: Header + HeaderFormat>(&self) -> Option<&H> {
self.data.get(&UniCase(Borrowed(header_name::<H>()))).and_then(Item::typed::<H>)
self.data.get(&UniCase(Cow::Borrowed(header_name::<H>()))).and_then(Item::typed::<H>)
}
/// Get a mutable reference to the header field's value, if it exists.
pub fn get_mut<H: Header + HeaderFormat>(&mut self) -> Option<&mut H> {
self.data.get_mut(&UniCase(Borrowed(header_name::<H>()))).and_then(Item::typed_mut::<H>)
self.data.get_mut(&UniCase(Cow::Borrowed(header_name::<H>()))).and_then(Item::typed_mut::<H>)
}
/// Returns a boolean of whether a certain header is in the map.
@@ -196,13 +194,13 @@ impl Headers {
/// let has_type = headers.has::<ContentType>();
/// ```
pub fn has<H: Header + HeaderFormat>(&self) -> bool {
self.data.contains_key(&UniCase(Borrowed(header_name::<H>())))
self.data.contains_key(&UniCase(Cow::Borrowed(header_name::<H>())))
}
/// Removes a header from the map, if one existed.
/// Returns true if a header has been removed.
pub fn remove<H: Header + HeaderFormat>(&mut self) -> bool {
self.data.remove(&UniCase(Borrowed(header_name::<H>()))).is_some()
self.data.remove(&UniCase(Cow::Borrowed(header_name::<H>()))).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<H: Header>(&self) -> bool {
UniCase(header_name::<H>().into_cow()) == *self.0
UniCase(Cow::Borrowed(header_name::<H>())) == *self.0
}
/// Get the Header name as a slice.

View File

@@ -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 <StatusCode as FromPrimitive>::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};

View File

@@ -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))]

View File

@@ -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 {