Merge pull request #427 from reem/cowstr-hack
fix(headers): Add CowStr as a temporary hack to build on beta.
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