6
6
//! are already provided, such as `Host`, `ContentType`, `UserAgent`, and others.
7
7
use std:: any:: Any ;
8
8
use std:: ascii:: { AsciiExt , AsciiCast } ;
9
+ use std:: borrow:: { Borrowed , Owned } ;
9
10
use std:: fmt:: { mod, Show } ;
10
11
use std:: intrinsics:: TypeId ;
11
12
use std:: raw:: TraitObject ;
12
- use std:: str:: { SendStr , Slice , Owned } ;
13
+ use std:: str:: SendStr ;
13
14
use std:: collections:: HashMap ;
14
15
use std:: collections:: hash_map:: { Entries , Occupied , Vacant } ;
15
16
use std:: sync:: RWLock ;
@@ -95,7 +96,7 @@ fn header_name<T: Header>() -> &'static str {
95
96
/// A map of header fields on requests and responses.
96
97
#[ deriving( Clone ) ]
97
98
pub struct Headers {
98
- data : HashMap < CaseInsensitive < SendStr > , RWLock < Item > >
99
+ data : HashMap < CaseInsensitive , RWLock < Item > >
99
100
}
100
101
101
102
impl Headers {
@@ -136,7 +137,7 @@ impl Headers {
136
137
///
137
138
/// The field is determined by the type of the value being set.
138
139
pub fn set < H : Header + HeaderFormat > ( & mut self , value : H ) {
139
- self . data . insert ( CaseInsensitive ( Slice ( header_name :: < H > ( ) ) ) ,
140
+ self . data . insert ( CaseInsensitive ( Borrowed ( header_name :: < H > ( ) ) ) ,
140
141
RWLock :: new ( Item :: typed ( box value as Box < HeaderFormat + Send + Sync > ) ) ) ;
141
142
}
142
143
@@ -154,7 +155,7 @@ impl Headers {
154
155
pub fn get_raw ( & self , name : & str ) -> Option < & [ Vec < u8 > ] > {
155
156
self . data
156
157
// FIXME(reem): Find a better way to do this lookup without find_equiv.
157
- . get ( & CaseInsensitive ( Slice ( unsafe { mem:: transmute :: < & str , & str > ( name) } ) ) )
158
+ . get ( & CaseInsensitive ( Borrowed ( unsafe { mem:: transmute :: < & str , & str > ( name) } ) ) )
158
159
. and_then ( |item| {
159
160
let lock = item. read ( ) ;
160
161
if let Some ( ref raw) = lock. raw {
@@ -177,8 +178,8 @@ impl Headers {
177
178
/// # let mut headers = Headers::new();
178
179
/// headers.set_raw("content-length", vec!["5".as_bytes().to_vec()]);
179
180
/// ```
180
- pub fn set_raw < K : IntoMaybeOwned < ' static > > ( & mut self , name : K , value : Vec < Vec < u8 > > ) {
181
- self . data . insert ( CaseInsensitive ( name. into_maybe_owned ( ) ) , RWLock :: new ( Item :: raw ( value) ) ) ;
181
+ pub fn set_raw < K : IntoCow < ' static , String , str > > ( & mut self , name : K , value : Vec < Vec < u8 > > ) {
182
+ self . data . insert ( CaseInsensitive ( name. into_cow ( ) ) , RWLock :: new ( Item :: raw ( value) ) ) ;
182
183
}
183
184
184
185
/// Get a reference to the header field's value, if it exists.
@@ -200,7 +201,7 @@ impl Headers {
200
201
}
201
202
202
203
fn get_or_parse < H : Header + HeaderFormat > ( & self ) -> Option < & RWLock < Item > > {
203
- self . data . get ( & CaseInsensitive ( Slice ( header_name :: < H > ( ) ) ) ) . and_then ( |item| get_or_parse :: < H > ( item) )
204
+ self . data . get ( & CaseInsensitive ( Borrowed ( header_name :: < H > ( ) ) ) ) . and_then ( |item| get_or_parse :: < H > ( item) )
204
205
}
205
206
206
207
/// Returns a boolean of whether a certain header is in the map.
@@ -214,13 +215,13 @@ impl Headers {
214
215
/// let has_type = headers.has::<ContentType>();
215
216
/// ```
216
217
pub fn has < H : Header + HeaderFormat > ( & self ) -> bool {
217
- self . data . contains_key ( & CaseInsensitive ( Slice ( header_name :: < H > ( ) ) ) )
218
+ self . data . contains_key ( & CaseInsensitive ( Borrowed ( header_name :: < H > ( ) ) ) )
218
219
}
219
220
220
221
/// Removes a header from the map, if one existed.
221
222
/// Returns true if a header has been removed.
222
223
pub fn remove < H : Header + HeaderFormat > ( & mut self ) -> bool {
223
- self . data . remove ( & CaseInsensitive ( Slice ( Header :: header_name ( None :: < H > ) ) ) ) . is_some ( )
224
+ self . data . remove ( & CaseInsensitive ( Borrowed ( Header :: header_name ( None :: < H > ) ) ) ) . is_some ( )
224
225
}
225
226
226
227
/// Returns an iterator over the header fields.
@@ -252,7 +253,7 @@ impl fmt::Show for Headers {
252
253
253
254
/// An `Iterator` over the fields in a `Headers` map.
254
255
pub struct HeadersItems < ' a > {
255
- inner : Entries < ' a , CaseInsensitive < SendStr > , RWLock < Item > >
256
+ inner : Entries < ' a , CaseInsensitive , RWLock < Item > >
256
257
}
257
258
258
259
impl < ' a > Iterator < HeaderView < ' a > > for HeadersItems < ' a > {
@@ -265,13 +266,13 @@ impl<'a> Iterator<HeaderView<'a>> for HeadersItems<'a> {
265
266
}
266
267
267
268
/// Returned with the `HeadersItems` iterator.
268
- pub struct HeaderView < ' a > ( & ' a CaseInsensitive < SendStr > , & ' a RWLock < Item > ) ;
269
+ pub struct HeaderView < ' a > ( & ' a CaseInsensitive , & ' a RWLock < Item > ) ;
269
270
270
271
impl < ' a > HeaderView < ' a > {
271
272
/// Check if a HeaderView is a certain Header.
272
273
#[ inline]
273
274
pub fn is < H : Header > ( & self ) -> bool {
274
- CaseInsensitive ( header_name :: < H > ( ) . into_maybe_owned ( ) ) == * self . 0
275
+ CaseInsensitive ( header_name :: < H > ( ) . into_cow ( ) ) == * self . 0
275
276
}
276
277
277
278
/// Get the Header name as a slice.
@@ -432,40 +433,44 @@ impl fmt::Show for Box<HeaderFormat + Send + Sync> {
432
433
}
433
434
}
434
435
435
- #[ deriving( Clone ) ]
436
- struct CaseInsensitive < S : Str > ( S ) ;
436
+ //#[deriving(Clone)]
437
+ struct CaseInsensitive ( SendStr ) ;
438
+
439
+ impl Clone for CaseInsensitive {
440
+ fn clone ( & self ) -> CaseInsensitive {
441
+ CaseInsensitive ( ( * self . 0 ) . clone ( ) . into_cow ( ) )
442
+ }
443
+ }
437
444
438
- impl < S : Str > Str for CaseInsensitive < S > {
445
+ impl Str for CaseInsensitive {
439
446
fn as_slice ( & self ) -> & str {
440
447
let CaseInsensitive ( ref s) = * self ;
441
448
s. as_slice ( )
442
449
}
443
450
444
451
}
445
452
446
- impl < S : Str > fmt:: Show for CaseInsensitive < S > {
453
+ impl fmt:: Show for CaseInsensitive {
447
454
fn fmt ( & self , fmt : & mut fmt:: Formatter ) -> fmt:: Result {
448
455
self . as_slice ( ) . fmt ( fmt)
449
456
}
450
457
}
451
458
452
- impl < S : Str > PartialEq for CaseInsensitive < S > {
453
- fn eq ( & self , other : & CaseInsensitive < S > ) -> bool {
459
+ impl PartialEq for CaseInsensitive {
460
+ fn eq ( & self , other : & CaseInsensitive ) -> bool {
454
461
self . as_slice ( ) . eq_ignore_ascii_case ( other. as_slice ( ) )
455
462
}
456
463
}
457
464
458
- impl < S : Str > Eq for CaseInsensitive < S > { }
465
+ impl Eq for CaseInsensitive { }
459
466
460
- impl < S : Str , S2 : Str > Equiv < CaseInsensitive < S2 > > for CaseInsensitive < S > {
461
- fn equiv ( & self , other : & CaseInsensitive < S2 > ) -> bool {
462
- let left = CaseInsensitive ( self . as_slice ( ) ) ;
463
- let right = CaseInsensitive ( other. as_slice ( ) ) ;
464
- left == right
467
+ impl Equiv < CaseInsensitive > for CaseInsensitive {
468
+ fn equiv ( & self , other : & CaseInsensitive ) -> bool {
469
+ self == other
465
470
}
466
471
}
467
472
468
- impl < S : Str , H : hash:: Writer > hash:: Hash < H > for CaseInsensitive < S > {
473
+ impl < H : hash:: Writer > hash:: Hash < H > for CaseInsensitive {
469
474
#[ inline]
470
475
fn hash ( & self , hasher : & mut H ) {
471
476
for b in self . as_slice ( ) . bytes ( ) {
@@ -491,7 +496,7 @@ impl<H: HeaderFormat> Show for HeaderFormatter<H> {
491
496
mod tests {
492
497
use std:: io:: MemReader ;
493
498
use std:: fmt;
494
- use std:: str :: Slice ;
499
+ use std:: borrow :: Borrowed ;
495
500
use std:: hash:: sip:: hash;
496
501
use mime:: { Mime , Text , Plain } ;
497
502
use super :: CaseInsensitive ;
@@ -506,8 +511,8 @@ mod tests {
506
511
507
512
#[ test]
508
513
fn test_case_insensitive ( ) {
509
- let a = CaseInsensitive ( Slice ( "foobar" ) ) ;
510
- let b = CaseInsensitive ( Slice ( "FOOBAR" ) ) ;
514
+ let a = CaseInsensitive ( Borrowed ( "foobar" ) ) ;
515
+ let b = CaseInsensitive ( Borrowed ( "FOOBAR" ) ) ;
511
516
512
517
assert_eq ! ( a, b) ;
513
518
assert_eq ! ( hash( & a) , hash( & b) ) ;
0 commit comments