@@ -9,6 +9,7 @@ use std::borrow::{Cow, ToOwned};
9
9
use std:: collections:: HashMap ;
10
10
use std:: collections:: hash_map:: { Iter , Entry } ;
11
11
use std:: iter:: { FromIterator , IntoIterator } ;
12
+ use std:: ops:: { Deref , DerefMut } ;
12
13
use std:: { mem, fmt} ;
13
14
14
15
use { httparse, traitobject} ;
@@ -26,7 +27,7 @@ mod internals;
26
27
mod shared;
27
28
pub mod parsing;
28
29
29
- type HeaderName = UniCase < Cow < ' static , str > > ;
30
+ type HeaderName = UniCase < CowStr > ;
30
31
31
32
/// A trait for any object that will represent a header field and value.
32
33
///
@@ -117,7 +118,7 @@ impl Headers {
117
118
let mut headers = Headers :: new ( ) ;
118
119
for header in raw {
119
120
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 ( ) ) ) ) ;
121
122
let mut item = match headers. data . entry ( name) {
122
123
Entry :: Vacant ( entry) => entry. insert ( Item :: new_raw ( vec ! [ ] ) ) ,
123
124
Entry :: Occupied ( entry) => entry. into_mut ( )
@@ -133,7 +134,7 @@ impl Headers {
133
134
///
134
135
/// The field is determined by the type of the value being set.
135
136
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 > ( ) ) ) ) ,
137
138
Item :: new_typed ( Box :: new ( value) ) ) ;
138
139
}
139
140
@@ -150,7 +151,7 @@ impl Headers {
150
151
/// ```
151
152
pub fn get_raw ( & self , name : & str ) -> Option < & [ Vec < u8 > ] > {
152
153
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) } ) ) ) )
154
155
. map ( Item :: raw)
155
156
}
156
157
@@ -164,22 +165,24 @@ impl Headers {
164
165
/// headers.set_raw("content-length", vec![b"5".to_vec()]);
165
166
/// ```
166
167
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) ) ;
168
169
}
169
170
170
171
/// Remove a header set by set_raw
171
172
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
+ ) ;
173
176
}
174
177
175
178
/// Get a reference to the header field's value, if it exists.
176
179
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 > )
178
181
}
179
182
180
183
/// Get a mutable reference to the header field's value, if it exists.
181
184
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 > )
183
186
}
184
187
185
188
/// Returns a boolean of whether a certain header is in the map.
@@ -193,13 +196,13 @@ impl Headers {
193
196
/// let has_type = headers.has::<ContentType>();
194
197
/// ```
195
198
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 > ( ) ) ) ) )
197
200
}
198
201
199
202
/// Removes a header from the map, if one existed.
200
203
/// Returns true if a header has been removed.
201
204
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 ( )
203
206
}
204
207
205
208
/// Returns an iterator over the header fields.
@@ -263,7 +266,7 @@ impl<'a> HeaderView<'a> {
263
266
/// Check if a HeaderView is a certain Header.
264
267
#[ inline]
265
268
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
267
270
}
268
271
269
272
/// Get the Header name as a slice.
@@ -341,6 +344,42 @@ impl<'a, H: HeaderFormat> fmt::Debug for HeaderFormatter<'a, H> {
341
344
}
342
345
}
343
346
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
+
344
383
#[ cfg( test) ]
345
384
mod tests {
346
385
use std:: fmt;
0 commit comments