From e2e93c5d5fd08d9ffa29aa3af57532219f7eddd1 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Wed, 3 Sep 2014 11:12:04 -0700 Subject: [PATCH] add + 'static bounds to Header trait --- src/header.rs | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/src/header.rs b/src/header.rs index 9f229a85..69acb03a 100644 --- a/src/header.rs +++ b/src/header.rs @@ -27,8 +27,11 @@ use rfc7230::read_header; use {HttpResult}; /// A trait for any object that will represent a header field and value. -pub trait Header: Any { +pub trait Header: Any + 'static { /// Returns the name of the header field this belongs to. + /// + /// The market `Option` is to hint to the type system which implementation + /// to call. This can be done away with once UFCS arrives. fn header_name(marker: Option) -> &'static str; /// Parse a header from a raw stream of bytes. /// @@ -106,7 +109,7 @@ impl Headers { /// Set a header field to the corresponding value. /// /// The field is determined by the type of the value being set. - pub fn set(&mut self, value: H) { + pub fn set(&mut self, value: H) { self.data.insert(header_name::(), Typed(box value)); } @@ -119,12 +122,12 @@ impl Headers { /// # let mut headers = Headers::new(); /// let content_type = headers.get::(); /// ``` - pub fn get(&mut self) -> Option { + pub fn get(&mut self) -> Option { self.get_ref().map(|v: &H| v.clone()) } /// Get a reference to the header field's value, if it exists. - pub fn get_ref(&mut self) -> Option<&H> { + pub fn get_ref(&mut self) -> Option<&H> { self.data.find_mut(&header_name::()).and_then(|item| { debug!("get_ref, name={}, val={}", header_name::(), item); let header = match *item { @@ -136,7 +139,7 @@ impl Headers { }, Typed(..) => return Some(item) }; - *item = Typed(box header as Box
); + *item = Typed(box header as Box
); Some(item) }).and_then(|item| { debug!("downcasting {}", item); @@ -162,7 +165,7 @@ impl Headers { /// # let mut headers = Headers::new(); /// let has_type = headers.has::(); /// ``` - pub fn has(&self) -> bool { + pub fn has(&self) -> bool { self.data.contains_key(&header_name::()) } @@ -227,7 +230,7 @@ impl Mutable for Headers { enum Item { Raw(Vec>), - Typed(Box
) + Typed(Box
) } impl fmt::Show for Item { @@ -498,6 +501,27 @@ impl Header for UserAgent { } } +/// The `Server` header field. +/// +/// They can contain any value, so it just wraps a `String`. +#[deriving(Clone, PartialEq, Show)] +pub struct Server(pub String); + +impl Header for Server { + fn header_name(_: Option) -> &'static str { + "server" + } + + fn parse_header(raw: &[Vec]) -> Option { + from_one_raw_str(raw).map(|s| Server(s)) + } + + fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let Server(ref value) = *self; + value.fmt(fmt) + } +} + fn from_one_raw_str(raw: &[Vec]) -> Option { if raw.len() != 1 { return None;