Skip to content

Commit 4263a01

Browse files
committed
convert to using Cow
1 parent c77cd3d commit 4263a01

File tree

3 files changed

+49
-37
lines changed

3 files changed

+49
-37
lines changed

src/client/response.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,9 @@ impl Reader for Response {
9595

9696
#[cfg(test)]
9797
mod tests {
98+
use std::borrow::Borrowed;
9899
use std::boxed::BoxAny;
99100
use std::io::BufferedReader;
100-
use std::str::Slice;
101101

102102
use header::Headers;
103103
use http::HttpReader::EofReader;
@@ -117,7 +117,7 @@ mod tests {
117117
headers: Headers::new(),
118118
version: version::HttpVersion::Http11,
119119
body: EofReader(BufferedReader::new(box MockStream::new() as Box<NetworkStream + Send>)),
120-
status_raw: RawStatus(200, Slice("OK"))
120+
status_raw: RawStatus(200, Borrowed("OK"))
121121
};
122122

123123
let b = res.into_inner().downcast::<MockStream>().unwrap();

src/header/mod.rs

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
//! are already provided, such as `Host`, `ContentType`, `UserAgent`, and others.
77
use std::any::Any;
88
use std::ascii::{AsciiExt, AsciiCast};
9+
use std::borrow::{Borrowed, Owned};
910
use std::fmt::{mod, Show};
1011
use std::intrinsics::TypeId;
1112
use std::raw::TraitObject;
12-
use std::str::{SendStr, Slice, Owned};
13+
use std::str::SendStr;
1314
use std::collections::HashMap;
1415
use std::collections::hash_map::{Entries, Occupied, Vacant};
1516
use std::sync::RWLock;
@@ -95,7 +96,7 @@ fn header_name<T: Header>() -> &'static str {
9596
/// A map of header fields on requests and responses.
9697
#[deriving(Clone)]
9798
pub struct Headers {
98-
data: HashMap<CaseInsensitive<SendStr>, RWLock<Item>>
99+
data: HashMap<CaseInsensitive, RWLock<Item>>
99100
}
100101

101102
impl Headers {
@@ -136,7 +137,7 @@ impl Headers {
136137
///
137138
/// The field is determined by the type of the value being set.
138139
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>())),
140141
RWLock::new(Item::typed(box value as Box<HeaderFormat + Send + Sync>)));
141142
}
142143

@@ -154,7 +155,7 @@ impl Headers {
154155
pub fn get_raw(&self, name: &str) -> Option<&[Vec<u8>]> {
155156
self.data
156157
// 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) })))
158159
.and_then(|item| {
159160
let lock = item.read();
160161
if let Some(ref raw) = lock.raw {
@@ -177,8 +178,8 @@ impl Headers {
177178
/// # let mut headers = Headers::new();
178179
/// headers.set_raw("content-length", vec!["5".as_bytes().to_vec()]);
179180
/// ```
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)));
182183
}
183184

184185
/// Get a reference to the header field's value, if it exists.
@@ -200,7 +201,7 @@ impl Headers {
200201
}
201202

202203
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))
204205
}
205206

206207
/// Returns a boolean of whether a certain header is in the map.
@@ -214,13 +215,13 @@ impl Headers {
214215
/// let has_type = headers.has::<ContentType>();
215216
/// ```
216217
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>())))
218219
}
219220

220221
/// Removes a header from the map, if one existed.
221222
/// Returns true if a header has been removed.
222223
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()
224225
}
225226

226227
/// Returns an iterator over the header fields.
@@ -252,7 +253,7 @@ impl fmt::Show for Headers {
252253

253254
/// An `Iterator` over the fields in a `Headers` map.
254255
pub struct HeadersItems<'a> {
255-
inner: Entries<'a, CaseInsensitive<SendStr>, RWLock<Item>>
256+
inner: Entries<'a, CaseInsensitive, RWLock<Item>>
256257
}
257258

258259
impl<'a> Iterator<HeaderView<'a>> for HeadersItems<'a> {
@@ -265,13 +266,13 @@ impl<'a> Iterator<HeaderView<'a>> for HeadersItems<'a> {
265266
}
266267

267268
/// 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>);
269270

270271
impl<'a> HeaderView<'a> {
271272
/// Check if a HeaderView is a certain Header.
272273
#[inline]
273274
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
275276
}
276277

277278
/// Get the Header name as a slice.
@@ -432,40 +433,44 @@ impl fmt::Show for Box<HeaderFormat + Send + Sync> {
432433
}
433434
}
434435

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+
}
437444

438-
impl<S: Str> Str for CaseInsensitive<S> {
445+
impl Str for CaseInsensitive {
439446
fn as_slice(&self) -> &str {
440447
let CaseInsensitive(ref s) = *self;
441448
s.as_slice()
442449
}
443450

444451
}
445452

446-
impl<S: Str> fmt::Show for CaseInsensitive<S> {
453+
impl fmt::Show for CaseInsensitive {
447454
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
448455
self.as_slice().fmt(fmt)
449456
}
450457
}
451458

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 {
454461
self.as_slice().eq_ignore_ascii_case(other.as_slice())
455462
}
456463
}
457464

458-
impl<S: Str> Eq for CaseInsensitive<S> {}
465+
impl Eq for CaseInsensitive {}
459466

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
465470
}
466471
}
467472

468-
impl<S: Str, H: hash::Writer> hash::Hash<H> for CaseInsensitive<S> {
473+
impl<H: hash::Writer> hash::Hash<H> for CaseInsensitive {
469474
#[inline]
470475
fn hash(&self, hasher: &mut H) {
471476
for b in self.as_slice().bytes() {
@@ -491,7 +496,7 @@ impl<H: HeaderFormat> Show for HeaderFormatter<H> {
491496
mod tests {
492497
use std::io::MemReader;
493498
use std::fmt;
494-
use std::str::Slice;
499+
use std::borrow::Borrowed;
495500
use std::hash::sip::hash;
496501
use mime::{Mime, Text, Plain};
497502
use super::CaseInsensitive;
@@ -506,8 +511,8 @@ mod tests {
506511

507512
#[test]
508513
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"));
511516

512517
assert_eq!(a, b);
513518
assert_eq!(hash(&a), hash(&b));

src/http.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
//! Pieces pertaining to the HTTP message protocol.
2+
use std::borrow::{Borrowed, Owned};
23
use std::cmp::min;
34
use std::fmt;
45
use std::io::{mod, Reader, IoResult, BufWriter};
56
use std::num::from_u16;
6-
use std::str::{mod, SendStr, Slice, Owned};
7+
use std::str::{mod, SendStr};
78

89
use url::Url;
910

@@ -559,9 +560,15 @@ pub fn read_request_line<R: Reader>(stream: &mut R) -> HttpResult<RequestLine> {
559560
pub type StatusLine = (HttpVersion, RawStatus);
560561

561562
/// The raw status code and reason-phrase.
562-
#[deriving(PartialEq, Show, Clone)]
563+
#[deriving(PartialEq, Show)]
563564
pub struct RawStatus(pub u16, pub SendStr);
564565

566+
impl Clone for RawStatus {
567+
fn clone(&self) -> RawStatus {
568+
RawStatus(self.0, (*self.1).clone().into_cow())
569+
}
570+
}
571+
565572
/// Read the StatusLine, such as `HTTP/1.1 200 OK`.
566573
///
567574
/// > The first line of a response message is the status-line, consisting
@@ -632,7 +639,7 @@ pub fn read_status<R: Reader>(stream: &mut R) -> HttpResult<RawStatus> {
632639
Some(status) => match status.canonical_reason() {
633640
Some(phrase) => {
634641
if phrase == reason {
635-
Slice(phrase)
642+
Borrowed(phrase)
636643
} else {
637644
Owned(reason.into_string())
638645
}
@@ -657,7 +664,7 @@ fn expect(r: IoResult<u8>, expected: u8) -> HttpResult<()> {
657664
#[cfg(test)]
658665
mod tests {
659666
use std::io::{mod, MemReader, MemWriter};
660-
use std::str::{Slice, Owned};
667+
use std::borrow::{Borrowed, Owned};
661668
use test::Bencher;
662669
use uri::RequestUri;
663670
use uri::RequestUri::{Star, AbsoluteUri, AbsolutePath, Authority};
@@ -727,8 +734,8 @@ mod tests {
727734
assert_eq!(read_status(&mut mem(s)), result);
728735
}
729736

730-
read("200 OK\r\n", Ok(RawStatus(200, Slice("OK"))));
731-
read("404 Not Found\r\n", Ok(RawStatus(404, Slice("Not Found"))));
737+
read("200 OK\r\n", Ok(RawStatus(200, Borrowed("OK"))));
738+
read("404 Not Found\r\n", Ok(RawStatus(404, Borrowed("Not Found"))));
732739
read("200 crazy pants\r\n", Ok(RawStatus(200, Owned("crazy pants".to_string()))));
733740
}
734741

@@ -774,7 +781,7 @@ mod tests {
774781
#[bench]
775782
fn bench_read_status(b: &mut Bencher) {
776783
b.bytes = b"404 Not Found\r\n".len() as u64;
777-
b.iter(|| assert_eq!(read_status(&mut mem("404 Not Found\r\n")), Ok(RawStatus(404, Slice("Not Found")))));
784+
b.iter(|| assert_eq!(read_status(&mut mem("404 Not Found\r\n")), Ok(RawStatus(404, Borrowed("Not Found")))));
778785
}
779786

780787
}

0 commit comments

Comments
 (0)