Merge pull request #118 from hyperium/headers-clone

make Headers implement Clone
This commit is contained in:
Jonathan Reem
2014-11-21 05:16:38 -08:00
4 changed files with 24 additions and 2 deletions

View File

@@ -44,6 +44,7 @@ fn bench_curl(b: &mut test::Bencher) {
listening.close().unwrap() listening.close().unwrap()
} }
#[deriving(Clone)]
struct Foo; struct Foo;
impl hyper::header::Header for Foo { impl hyper::header::Header for Foo {

View File

@@ -68,6 +68,7 @@ fn bench_mock_curl(b: &mut test::Bencher) {
}); });
} }
#[deriving(Clone)]
struct Foo; struct Foo;
impl hyper::header::Header for Foo { impl hyper::header::Header for Foo {

View File

@@ -39,7 +39,7 @@ impl<S: Scheme> HeaderFormat for Authorization<S> {
} }
/// An Authorization scheme to be used in the header. /// An Authorization scheme to be used in the header.
pub trait Scheme: FromStr + Send + Sync { pub trait Scheme: FromStr + Clone + Send + Sync {
/// An optional Scheme name. /// An optional Scheme name.
/// ///
/// For example, `Basic asdf` has the name `Basic`. The Option<Self> is /// For example, `Basic asdf` has the name `Basic`. The Option<Self> is

View File

@@ -41,17 +41,22 @@ pub trait Header: Typeable + Send + Sync {
/// than one field value. If that's the case, you **should** return `None` /// than one field value. If that's the case, you **should** return `None`
/// if `raw.len() > 1`. /// if `raw.len() > 1`.
fn parse_header(raw: &[Vec<u8>]) -> Option<Self>; fn parse_header(raw: &[Vec<u8>]) -> Option<Self>;
} }
/// 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.
/// ///
/// This trait represents the formatting of a Header for output to a TcpStream. /// This trait represents the formatting of a Header for output to a TcpStream.
pub trait HeaderFormat: Typeable + Send + Sync { pub trait HeaderFormat: Clone + Typeable + Send + Sync {
/// Format a header to be output into a TcpStream. /// Format a header to be output into a TcpStream.
/// ///
/// This method is not allowed to introduce an Err not produced /// This method is not allowed to introduce an Err not produced
/// by the passed-in Formatter. /// by the passed-in Formatter.
fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result; fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result;
#[doc(hidden)]
#[inline]
fn clone_box(&self) -> Box<HeaderFormat + Sync + Send> { box self.clone() }
} }
#[doc(hidden)] #[doc(hidden)]
@@ -81,12 +86,19 @@ impl<'a> UncheckedAnyMutDowncast<'a> for &'a mut HeaderFormat {
} }
} }
impl Clone for Box<HeaderFormat + Send + Sync> {
fn clone(&self) -> Box<HeaderFormat + Send + Sync> {
self.clone_box()
}
}
fn header_name<T: Header + HeaderFormat>() -> &'static str { fn header_name<T: Header + HeaderFormat>() -> &'static str {
let name = Header::header_name(None::<T>); let name = Header::header_name(None::<T>);
name name
} }
/// A map of header fields on requests and responses. /// A map of header fields on requests and responses.
#[deriving(Clone)]
pub struct Headers { pub struct Headers {
data: HashMap<CaseInsensitive<SendStr>, RWLock<Item>> data: HashMap<CaseInsensitive<SendStr>, RWLock<Item>>
} }
@@ -318,6 +330,7 @@ impl<'a> fmt::Show for HeaderView<'a> {
} }
} }
#[deriving(Clone)]
struct Item { struct Item {
raw: Option<Vec<Vec<u8>>>, raw: Option<Vec<Vec<u8>>>,
typed: Option<Box<HeaderFormat + Send + Sync>> typed: Option<Box<HeaderFormat + Send + Sync>>
@@ -356,12 +369,19 @@ impl fmt::Show for Item {
} }
} }
impl Clone for RWLock<Item> {
fn clone(&self) -> RWLock<Item> {
RWLock::new(self.read().clone())
}
}
impl fmt::Show for Box<HeaderFormat + Send + Sync> { impl fmt::Show for Box<HeaderFormat + Send + Sync> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
(**self).fmt_header(fmt) (**self).fmt_header(fmt)
} }
} }
#[deriving(Clone)]
struct CaseInsensitive<S: Str>(S); struct CaseInsensitive<S: Str>(S);
impl<S: Str> Str for CaseInsensitive<S> { impl<S: Str> Str for CaseInsensitive<S> {