fix(headers): Add CowStr as a temporary hack to build on beta.
We can revert this PR when rust-lang/rust#23995 lands, but it won't land until after beta is cut.
This commit is contained in:
		| @@ -9,6 +9,7 @@ use std::borrow::{Cow, ToOwned}; | |||||||
| use std::collections::HashMap; | use std::collections::HashMap; | ||||||
| use std::collections::hash_map::{Iter, Entry}; | use std::collections::hash_map::{Iter, Entry}; | ||||||
| use std::iter::{FromIterator, IntoIterator}; | use std::iter::{FromIterator, IntoIterator}; | ||||||
|  | use std::ops::{Deref, DerefMut}; | ||||||
| use std::{mem, fmt}; | use std::{mem, fmt}; | ||||||
|  |  | ||||||
| use {httparse, traitobject}; | use {httparse, traitobject}; | ||||||
| @@ -26,7 +27,7 @@ mod internals; | |||||||
| mod shared; | mod shared; | ||||||
| pub mod parsing; | pub mod parsing; | ||||||
|  |  | ||||||
| type HeaderName = UniCase<Cow<'static, str>>; | type HeaderName = UniCase<CowStr>; | ||||||
|  |  | ||||||
| /// A trait for any object that will represent a header field and value. | /// A trait for any object that will represent a header field and value. | ||||||
| /// | /// | ||||||
| @@ -117,7 +118,7 @@ impl Headers { | |||||||
|         let mut headers = Headers::new(); |         let mut headers = Headers::new(); | ||||||
|         for header in raw { |         for header in raw { | ||||||
|             debug!("raw header: {:?}={:?}", header.name, &header.value[..]); |             debug!("raw header: {:?}={:?}", header.name, &header.value[..]); | ||||||
|             let name = UniCase(Cow::Owned(header.name.to_owned())); |             let name = UniCase(CowStr(Cow::Owned(header.name.to_owned()))); | ||||||
|             let mut item = match headers.data.entry(name) { |             let mut item = match headers.data.entry(name) { | ||||||
|                 Entry::Vacant(entry) => entry.insert(Item::new_raw(vec![])), |                 Entry::Vacant(entry) => entry.insert(Item::new_raw(vec![])), | ||||||
|                 Entry::Occupied(entry) => entry.into_mut() |                 Entry::Occupied(entry) => entry.into_mut() | ||||||
| @@ -133,7 +134,7 @@ impl Headers { | |||||||
|     /// |     /// | ||||||
|     /// The field is determined by the type of the value being set. |     /// The field is determined by the type of the value being set. | ||||||
|     pub fn set<H: Header + HeaderFormat>(&mut self, value: H) { |     pub fn set<H: Header + HeaderFormat>(&mut self, value: H) { | ||||||
|         self.data.insert(UniCase(Cow::Borrowed(header_name::<H>())), |         self.data.insert(UniCase(CowStr(Cow::Borrowed(header_name::<H>()))), | ||||||
|                          Item::new_typed(Box::new(value))); |                          Item::new_typed(Box::new(value))); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -150,7 +151,7 @@ impl Headers { | |||||||
|     /// ``` |     /// ``` | ||||||
|     pub fn get_raw(&self, name: &str) -> Option<&[Vec<u8>]> { |     pub fn get_raw(&self, name: &str) -> Option<&[Vec<u8>]> { | ||||||
|         self.data |         self.data | ||||||
|             .get(&UniCase(Cow::Borrowed(unsafe { mem::transmute::<&str, &str>(name) }))) |             .get(&UniCase(CowStr(Cow::Borrowed(unsafe { mem::transmute::<&str, &str>(name) })))) | ||||||
|             .map(Item::raw) |             .map(Item::raw) | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -164,22 +165,24 @@ impl Headers { | |||||||
|     /// headers.set_raw("content-length", vec![b"5".to_vec()]); |     /// headers.set_raw("content-length", vec![b"5".to_vec()]); | ||||||
|     /// ``` |     /// ``` | ||||||
|     pub fn set_raw<K: Into<Cow<'static, str>>>(&mut self, name: K, value: Vec<Vec<u8>>) { |     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)); |         self.data.insert(UniCase(CowStr(name.into())), Item::new_raw(value)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// Remove a header set by set_raw |     /// Remove a header set by set_raw | ||||||
|     pub fn remove_raw(&mut self, name: &str) { |     pub fn remove_raw(&mut self, name: &str) { | ||||||
|         self.data.remove(&UniCase(Cow::Borrowed(name))); |         self.data.remove( | ||||||
|  |             &UniCase(CowStr(Cow::Borrowed(unsafe { mem::transmute::<&str, &str>(name) }))) | ||||||
|  |         ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// Get a reference to the header field's value, if it exists. |     /// Get a reference to the header field's value, if it exists. | ||||||
|     pub fn get<H: Header + HeaderFormat>(&self) -> Option<&H> { |     pub fn get<H: Header + HeaderFormat>(&self) -> Option<&H> { | ||||||
|         self.data.get(&UniCase(Cow::Borrowed(header_name::<H>()))).and_then(Item::typed::<H>) |         self.data.get(&UniCase(CowStr(Cow::Borrowed(header_name::<H>())))).and_then(Item::typed::<H>) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// Get a mutable reference to the header field's value, if it exists. |     /// 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> { |     pub fn get_mut<H: Header + HeaderFormat>(&mut self) -> Option<&mut H> { | ||||||
|         self.data.get_mut(&UniCase(Cow::Borrowed(header_name::<H>()))).and_then(Item::typed_mut::<H>) |         self.data.get_mut(&UniCase(CowStr(Cow::Borrowed(header_name::<H>())))).and_then(Item::typed_mut::<H>) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// Returns a boolean of whether a certain header is in the map. |     /// Returns a boolean of whether a certain header is in the map. | ||||||
| @@ -193,13 +196,13 @@ impl Headers { | |||||||
|     /// let has_type = headers.has::<ContentType>(); |     /// let has_type = headers.has::<ContentType>(); | ||||||
|     /// ``` |     /// ``` | ||||||
|     pub fn has<H: Header + HeaderFormat>(&self) -> bool { |     pub fn has<H: Header + HeaderFormat>(&self) -> bool { | ||||||
|         self.data.contains_key(&UniCase(Cow::Borrowed(header_name::<H>()))) |         self.data.contains_key(&UniCase(CowStr(Cow::Borrowed(header_name::<H>())))) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// Removes a header from the map, if one existed. |     /// Removes a header from the map, if one existed. | ||||||
|     /// Returns true if a header has been removed. |     /// Returns true if a header has been removed. | ||||||
|     pub fn remove<H: Header + HeaderFormat>(&mut self) -> bool { |     pub fn remove<H: Header + HeaderFormat>(&mut self) -> bool { | ||||||
|         self.data.remove(&UniCase(Cow::Borrowed(header_name::<H>()))).is_some() |         self.data.remove(&UniCase(CowStr(Cow::Borrowed(header_name::<H>())))).is_some() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// Returns an iterator over the header fields. |     /// Returns an iterator over the header fields. | ||||||
| @@ -263,7 +266,7 @@ impl<'a> HeaderView<'a> { | |||||||
|     /// Check if a HeaderView is a certain Header. |     /// Check if a HeaderView is a certain Header. | ||||||
|     #[inline] |     #[inline] | ||||||
|     pub fn is<H: Header>(&self) -> bool { |     pub fn is<H: Header>(&self) -> bool { | ||||||
|         UniCase(Cow::Borrowed(header_name::<H>())) == *self.0 |         UniCase(CowStr(Cow::Borrowed(header_name::<H>()))) == *self.0 | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// Get the Header name as a slice. |     /// Get the Header name as a slice. | ||||||
| @@ -341,6 +344,42 @@ impl<'a, H: HeaderFormat> fmt::Debug for HeaderFormatter<'a, H> { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[derive(Clone, Hash, Eq, PartialEq, PartialOrd, Ord)] | ||||||
|  | struct CowStr(Cow<'static, str>); | ||||||
|  |  | ||||||
|  | impl Deref for CowStr { | ||||||
|  |     type Target = Cow<'static, str>; | ||||||
|  |  | ||||||
|  |     fn deref(&self) -> &Cow<'static, str> { | ||||||
|  |         &self.0 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl fmt::Debug for CowStr { | ||||||
|  |     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||||
|  |         fmt::Debug::fmt(&self.0, fmt) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl fmt::Display for CowStr { | ||||||
|  |     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||||
|  |         fmt::Display::fmt(&self.0, fmt) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl DerefMut for CowStr { | ||||||
|  |     fn deref_mut(&mut self) -> &mut Cow<'static, str> { | ||||||
|  |         &mut self.0 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl AsRef<str> for CowStr { | ||||||
|  |     fn as_ref(&self) -> &str { | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| #[cfg(test)] | #[cfg(test)] | ||||||
| mod tests { | mod tests { | ||||||
|     use std::fmt; |     use std::fmt; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user