add + 'static bounds to Header trait
This commit is contained in:
		| @@ -27,8 +27,11 @@ use rfc7230::read_header; | |||||||
| use {HttpResult}; | use {HttpResult}; | ||||||
|  |  | ||||||
| /// 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. | ||||||
| pub trait Header: Any { | pub trait Header: Any + 'static { | ||||||
|     /// Returns the name of the header field this belongs to. |     /// 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<Self>) -> &'static str; |     fn header_name(marker: Option<Self>) -> &'static str; | ||||||
|     /// Parse a header from a raw stream of bytes. |     /// Parse a header from a raw stream of bytes. | ||||||
|     /// |     /// | ||||||
| @@ -106,7 +109,7 @@ impl Headers { | |||||||
|     /// Set a header field to the corresponding value. |     /// Set a header field to the corresponding value. | ||||||
|     /// |     /// | ||||||
|     /// The field is determined by the type of the value being set. |     /// The field is determined by the type of the value being set. | ||||||
|     pub fn set<H: Header + 'static>(&mut self, value: H) { |     pub fn set<H: Header>(&mut self, value: H) { | ||||||
|         self.data.insert(header_name::<H>(), Typed(box value)); |         self.data.insert(header_name::<H>(), Typed(box value)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -119,12 +122,12 @@ impl Headers { | |||||||
|     /// # let mut headers = Headers::new(); |     /// # let mut headers = Headers::new(); | ||||||
|     /// let content_type = headers.get::<ContentType>(); |     /// let content_type = headers.get::<ContentType>(); | ||||||
|     /// ``` |     /// ``` | ||||||
|     pub fn get<H: Header + Clone + 'static>(&mut self) -> Option<H> { |     pub fn get<H: Header + Clone>(&mut self) -> Option<H> { | ||||||
|         self.get_ref().map(|v: &H| v.clone()) |         self.get_ref().map(|v: &H| v.clone()) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// Get a reference to the header field's value, if it exists. |     /// Get a reference to the header field's value, if it exists. | ||||||
|     pub fn get_ref<H: Header + 'static>(&mut self) -> Option<&H> { |     pub fn get_ref<H: Header>(&mut self) -> Option<&H> { | ||||||
|         self.data.find_mut(&header_name::<H>()).and_then(|item| { |         self.data.find_mut(&header_name::<H>()).and_then(|item| { | ||||||
|             debug!("get_ref, name={}, val={}", header_name::<H>(), item); |             debug!("get_ref, name={}, val={}", header_name::<H>(), item); | ||||||
|             let header = match *item { |             let header = match *item { | ||||||
| @@ -136,7 +139,7 @@ impl Headers { | |||||||
|                 }, |                 }, | ||||||
|                 Typed(..) => return Some(item) |                 Typed(..) => return Some(item) | ||||||
|             }; |             }; | ||||||
|             *item = Typed(box header as Box<Header + 'static>); |             *item = Typed(box header as Box<Header>); | ||||||
|             Some(item) |             Some(item) | ||||||
|         }).and_then(|item| { |         }).and_then(|item| { | ||||||
|             debug!("downcasting {}", item); |             debug!("downcasting {}", item); | ||||||
| @@ -162,7 +165,7 @@ impl Headers { | |||||||
|     /// # let mut headers = Headers::new(); |     /// # let mut headers = Headers::new(); | ||||||
|     /// let has_type = headers.has::<ContentType>(); |     /// let has_type = headers.has::<ContentType>(); | ||||||
|     /// ``` |     /// ``` | ||||||
|     pub fn has<H: Header + 'static>(&self) -> bool { |     pub fn has<H: Header>(&self) -> bool { | ||||||
|         self.data.contains_key(&header_name::<H>()) |         self.data.contains_key(&header_name::<H>()) | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -227,7 +230,7 @@ impl Mutable for Headers { | |||||||
|  |  | ||||||
| enum Item { | enum Item { | ||||||
|     Raw(Vec<Vec<u8>>), |     Raw(Vec<Vec<u8>>), | ||||||
|     Typed(Box<Header + 'static>) |     Typed(Box<Header>) | ||||||
| } | } | ||||||
|  |  | ||||||
| impl fmt::Show for Item { | 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<Server>) -> &'static str { | ||||||
|  |         "server" | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn parse_header(raw: &[Vec<u8>]) -> Option<Server> { | ||||||
|  |         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<T: FromStr>(raw: &[Vec<u8>]) -> Option<T> { | fn from_one_raw_str<T: FromStr>(raw: &[Vec<u8>]) -> Option<T> { | ||||||
|     if raw.len() != 1 { |     if raw.len() != 1 { | ||||||
|         return None; |         return None; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user