Skip to content

Commit 8e06556

Browse files
committed
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.
1 parent 48bbf4a commit 8e06556

File tree

1 file changed

+50
-11
lines changed

1 file changed

+50
-11
lines changed

src/header/mod.rs

+50-11
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use std::borrow::{Cow, ToOwned};
99
use std::collections::HashMap;
1010
use std::collections::hash_map::{Iter, Entry};
1111
use std::iter::{FromIterator, IntoIterator};
12+
use std::ops::{Deref, DerefMut};
1213
use std::{mem, fmt};
1314

1415
use {httparse, traitobject};
@@ -26,7 +27,7 @@ mod internals;
2627
mod shared;
2728
pub mod parsing;
2829

29-
type HeaderName = UniCase<Cow<'static, str>>;
30+
type HeaderName = UniCase<CowStr>;
3031

3132
/// A trait for any object that will represent a header field and value.
3233
///
@@ -117,7 +118,7 @@ impl Headers {
117118
let mut headers = Headers::new();
118119
for header in raw {
119120
debug!("raw header: {:?}={:?}", header.name, &header.value[..]);
120-
let name = UniCase(Cow::Owned(header.name.to_owned()));
121+
let name = UniCase(CowStr(Cow::Owned(header.name.to_owned())));
121122
let mut item = match headers.data.entry(name) {
122123
Entry::Vacant(entry) => entry.insert(Item::new_raw(vec![])),
123124
Entry::Occupied(entry) => entry.into_mut()
@@ -133,7 +134,7 @@ impl Headers {
133134
///
134135
/// The field is determined by the type of the value being set.
135136
pub fn set<H: Header + HeaderFormat>(&mut self, value: H) {
136-
self.data.insert(UniCase(Cow::Borrowed(header_name::<H>())),
137+
self.data.insert(UniCase(CowStr(Cow::Borrowed(header_name::<H>()))),
137138
Item::new_typed(Box::new(value)));
138139
}
139140

@@ -150,7 +151,7 @@ impl Headers {
150151
/// ```
151152
pub fn get_raw(&self, name: &str) -> Option<&[Vec<u8>]> {
152153
self.data
153-
.get(&UniCase(Cow::Borrowed(unsafe { mem::transmute::<&str, &str>(name) })))
154+
.get(&UniCase(CowStr(Cow::Borrowed(unsafe { mem::transmute::<&str, &str>(name) }))))
154155
.map(Item::raw)
155156
}
156157

@@ -164,22 +165,24 @@ impl Headers {
164165
/// headers.set_raw("content-length", vec![b"5".to_vec()]);
165166
/// ```
166167
pub fn set_raw<K: Into<Cow<'static, str>>>(&mut self, name: K, value: Vec<Vec<u8>>) {
167-
self.data.insert(UniCase(name.into()), Item::new_raw(value));
168+
self.data.insert(UniCase(CowStr(name.into())), Item::new_raw(value));
168169
}
169170

170171
/// Remove a header set by set_raw
171172
pub fn remove_raw(&mut self, name: &str) {
172-
self.data.remove(&UniCase(Cow::Borrowed(name)));
173+
self.data.remove(
174+
&UniCase(CowStr(Cow::Borrowed(unsafe { mem::transmute::<&str, &str>(name) })))
175+
);
173176
}
174177

175178
/// Get a reference to the header field's value, if it exists.
176179
pub fn get<H: Header + HeaderFormat>(&self) -> Option<&H> {
177-
self.data.get(&UniCase(Cow::Borrowed(header_name::<H>()))).and_then(Item::typed::<H>)
180+
self.data.get(&UniCase(CowStr(Cow::Borrowed(header_name::<H>())))).and_then(Item::typed::<H>)
178181
}
179182

180183
/// Get a mutable reference to the header field's value, if it exists.
181184
pub fn get_mut<H: Header + HeaderFormat>(&mut self) -> Option<&mut H> {
182-
self.data.get_mut(&UniCase(Cow::Borrowed(header_name::<H>()))).and_then(Item::typed_mut::<H>)
185+
self.data.get_mut(&UniCase(CowStr(Cow::Borrowed(header_name::<H>())))).and_then(Item::typed_mut::<H>)
183186
}
184187

185188
/// Returns a boolean of whether a certain header is in the map.
@@ -193,13 +196,13 @@ impl Headers {
193196
/// let has_type = headers.has::<ContentType>();
194197
/// ```
195198
pub fn has<H: Header + HeaderFormat>(&self) -> bool {
196-
self.data.contains_key(&UniCase(Cow::Borrowed(header_name::<H>())))
199+
self.data.contains_key(&UniCase(CowStr(Cow::Borrowed(header_name::<H>()))))
197200
}
198201

199202
/// Removes a header from the map, if one existed.
200203
/// Returns true if a header has been removed.
201204
pub fn remove<H: Header + HeaderFormat>(&mut self) -> bool {
202-
self.data.remove(&UniCase(Cow::Borrowed(header_name::<H>()))).is_some()
205+
self.data.remove(&UniCase(CowStr(Cow::Borrowed(header_name::<H>())))).is_some()
203206
}
204207

205208
/// Returns an iterator over the header fields.
@@ -263,7 +266,7 @@ impl<'a> HeaderView<'a> {
263266
/// Check if a HeaderView is a certain Header.
264267
#[inline]
265268
pub fn is<H: Header>(&self) -> bool {
266-
UniCase(Cow::Borrowed(header_name::<H>())) == *self.0
269+
UniCase(CowStr(Cow::Borrowed(header_name::<H>()))) == *self.0
267270
}
268271

269272
/// Get the Header name as a slice.
@@ -341,6 +344,42 @@ impl<'a, H: HeaderFormat> fmt::Debug for HeaderFormatter<'a, H> {
341344
}
342345
}
343346

347+
#[derive(Clone, Hash, Eq, PartialEq, PartialOrd, Ord)]
348+
struct CowStr(Cow<'static, str>);
349+
350+
impl Deref for CowStr {
351+
type Target = Cow<'static, str>;
352+
353+
fn deref(&self) -> &Cow<'static, str> {
354+
&self.0
355+
}
356+
}
357+
358+
impl fmt::Debug for CowStr {
359+
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
360+
fmt::Debug::fmt(&self.0, fmt)
361+
}
362+
}
363+
364+
impl fmt::Display for CowStr {
365+
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
366+
fmt::Display::fmt(&self.0, fmt)
367+
}
368+
}
369+
370+
impl DerefMut for CowStr {
371+
fn deref_mut(&mut self) -> &mut Cow<'static, str> {
372+
&mut self.0
373+
}
374+
}
375+
376+
impl AsRef<str> for CowStr {
377+
fn as_ref(&self) -> &str {
378+
self
379+
}
380+
}
381+
382+
344383
#[cfg(test)]
345384
mod tests {
346385
use std::fmt;

0 commit comments

Comments
 (0)