Skip to content

chore(stability): remove into_cow feature gate #416

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 2, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 13 additions & 15 deletions src/header/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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()
Expand All @@ -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)));
}

Expand All @@ -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)
}

Expand All @@ -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.
Expand All @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
24 changes: 13 additions & 11 deletions src/http.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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))
},
Expand All @@ -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};
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -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))]
Expand Down
83 changes: 2 additions & 81 deletions src/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -305,7 +306,7 @@ impl StatusCode {

StatusCode::NotExtended => Some("Not Extended"),
StatusCode::NetworkAuthenticationRequired => Some("Network Authentication Required"),
_ => None
StatusCode::Unregistered(..) => None
}
}

Expand Down Expand Up @@ -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 {
Expand Down