feat(header): add Headers::append_raw
This commit is contained in:
		| @@ -33,7 +33,8 @@ impl Item { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[inline] |     #[inline] | ||||||
|     pub fn mut_raw(&mut self) -> &mut Raw { |     pub fn raw_mut(&mut self) -> &mut Raw { | ||||||
|  |         self.raw(); | ||||||
|         self.typed = PtrMapCell::new(); |         self.typed = PtrMapCell::new(); | ||||||
|         unsafe { |         unsafe { | ||||||
|             self.raw.get_mut() |             self.raw.get_mut() | ||||||
|   | |||||||
| @@ -216,6 +216,17 @@ impl<'a> fmt::Display for ValueString<'a> { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | struct HeaderValueString<'a, H: Header + 'a>(&'a H); | ||||||
|  |  | ||||||
|  | impl<'a, H: Header> fmt::Debug for HeaderValueString<'a, H> { | ||||||
|  |     #[inline] | ||||||
|  |     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||||
|  |         try!(f.write_str("\"")); | ||||||
|  |         try!(self.0.fmt_multi_header(&mut MultilineFormatter(Multi::Join(true, f)))); | ||||||
|  |         f.write_str("\"") | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| struct NewlineReplacer<'a, 'b: 'a>(&'a mut fmt::Formatter<'b>); | struct NewlineReplacer<'a, 'b: 'a>(&'a mut fmt::Formatter<'b>); | ||||||
|  |  | ||||||
| impl<'a, 'b> fmt::Write for NewlineReplacer<'a, 'b> { | impl<'a, 'b> fmt::Write for NewlineReplacer<'a, 'b> { | ||||||
| @@ -363,7 +374,7 @@ impl Headers { | |||||||
|     /// |     /// | ||||||
|     /// 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>(&mut self, value: H) { |     pub fn set<H: Header>(&mut self, value: H) { | ||||||
|         trace!("Headers.set( {:?}, {:?} )", header_name::<H>(), HeaderFormatter(&value)); |         trace!("Headers.set( {:?}, {:?} )", header_name::<H>(), HeaderValueString(&value)); | ||||||
|         self.data.insert(HeaderName(UniCase(Cow::Borrowed(header_name::<H>()))), |         self.data.insert(HeaderName(UniCase(Cow::Borrowed(header_name::<H>()))), | ||||||
|                          Item::new_typed(Box::new(value))); |                          Item::new_typed(Box::new(value))); | ||||||
|     } |     } | ||||||
| @@ -460,6 +471,33 @@ impl Headers { | |||||||
|         self.data.insert(HeaderName(UniCase(name)), Item::new_raw(value)); |         self.data.insert(HeaderName(UniCase(name)), Item::new_raw(value)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Append a value to raw value of this header. | ||||||
|  |     /// | ||||||
|  |     /// If a header already contains a value, this will add another line to it. | ||||||
|  |     /// | ||||||
|  |     /// If a header doesnot exist for this name, a new one will be created with | ||||||
|  |     /// the value. | ||||||
|  |     /// | ||||||
|  |     /// Example: | ||||||
|  |     /// | ||||||
|  |     /// ``` | ||||||
|  |     /// # use hyper::header::Headers; | ||||||
|  |     /// # let mut headers = Headers::new(); | ||||||
|  |     /// headers.append_raw("x-foo", b"bar".to_vec()); | ||||||
|  |     /// headers.append_raw("x-foo", b"quux".to_vec()); | ||||||
|  |     /// ``` | ||||||
|  |     pub fn append_raw<K: Into<Cow<'static, str>>, V: Into<Raw>>(&mut self, name: K, value: V) { | ||||||
|  |         let name = name.into(); | ||||||
|  |         let value = value.into(); | ||||||
|  |         trace!("Headers.append_raw( {:?}, {:?} )", name, value); | ||||||
|  |         let name = HeaderName(UniCase(name)); | ||||||
|  |         if let Some(item) = self.data.get_mut(&name) { | ||||||
|  |             item.raw_mut().push(value); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         self.data.insert(name, Item::new_raw(value)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /// Remove a header by name. |     /// Remove a header by name. | ||||||
|     pub fn remove_raw(&mut self, name: &str) { |     pub fn remove_raw(&mut self, name: &str) { | ||||||
|         trace!("Headers.remove_raw( {:?} )", name); |         trace!("Headers.remove_raw( {:?} )", name); | ||||||
| @@ -583,7 +621,7 @@ impl<'a> Extend<(&'a str, MemSlice)> for Headers { | |||||||
|                     entry.insert(Item::new_raw(self::raw::parsed(value))); |                     entry.insert(Item::new_raw(self::raw::parsed(value))); | ||||||
|                 } |                 } | ||||||
|                 Entry::Occupied(entry) => { |                 Entry::Occupied(entry) => { | ||||||
|                     self::raw::push(entry.into_mut().mut_raw(), value); |                     self::raw::push(entry.into_mut().raw_mut(), value); | ||||||
|                 } |                 } | ||||||
|             }; |             }; | ||||||
|         } |         } | ||||||
| @@ -625,8 +663,7 @@ deprecated! { | |||||||
| impl<'a, H: Header> fmt::Display for HeaderFormatter<'a, H> { | impl<'a, H: Header> fmt::Display for HeaderFormatter<'a, H> { | ||||||
|     #[inline] |     #[inline] | ||||||
|     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||||
|         let mut multi = MultilineFormatter(Multi::Join(true, f)); |         fmt::Debug::fmt(&HeaderValueString(self.0), f) | ||||||
|         self.0.fmt_multi_header(&mut multi) |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -806,6 +843,16 @@ mod tests { | |||||||
|         assert_eq!(headers.get(), Some(&ContentLength(20))); |         assert_eq!(headers.get(), Some(&ContentLength(20))); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     #[test] | ||||||
|  |     fn test_append_raw() { | ||||||
|  |         let mut headers = Headers::new(); | ||||||
|  |         headers.set(ContentLength(10)); | ||||||
|  |         headers.append_raw("content-LENGTH", b"20".to_vec()); | ||||||
|  |         assert_eq!(headers.get_raw("Content-length").unwrap(), &[b"10".to_vec(), b"20".to_vec()][..]); | ||||||
|  |         headers.append_raw("x-foo", "bar"); | ||||||
|  |         assert_eq!(headers.get_raw("x-foo").unwrap(), &[b"bar".to_vec()][..]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|     fn test_remove_raw() { |     fn test_remove_raw() { | ||||||
|         let mut headers = Headers::new(); |         let mut headers = Headers::new(); | ||||||
|   | |||||||
| @@ -36,8 +36,16 @@ impl Raw { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// Append a line to this `Raw` header value. |     /// Append a line to this `Raw` header value. | ||||||
|     pub fn push(&mut self, val: &[u8]) { |     pub fn push<V: Into<Raw>>(&mut self, val: V) { | ||||||
|         self.push_line(maybe_literal(val.into())); |         let raw = val.into(); | ||||||
|  |         match raw.0 { | ||||||
|  |             Lines::One(one) => self.push_line(one), | ||||||
|  |             Lines::Many(lines) => { | ||||||
|  |                 for line in lines { | ||||||
|  |                     self.push_line(line); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fn push_line(&mut self, line: Line) { |     fn push_line(&mut self, line: Line) { | ||||||
| @@ -121,27 +129,26 @@ impl From<Vec<Vec<u8>>> for Raw { | |||||||
| impl From<String> for Raw { | impl From<String> for Raw { | ||||||
|     #[inline] |     #[inline] | ||||||
|     fn from(val: String) -> Raw { |     fn from(val: String) -> Raw { | ||||||
|         let vec: Vec<u8> = val.into(); |         Raw::from(val.into_bytes()) | ||||||
|         vec.into() |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| impl From<Vec<u8>> for Raw { | impl From<Vec<u8>> for Raw { | ||||||
|     #[inline] |     #[inline] | ||||||
|     fn from(val: Vec<u8>) -> Raw { |     fn from(val: Vec<u8>) -> Raw { | ||||||
|         Raw(Lines::One(Line::from(val))) |         Raw(Lines::One(maybe_literal(val.into()))) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| impl From<&'static str> for Raw { | impl<'a> From<&'a str> for Raw { | ||||||
|     fn from(val: &'static str) -> Raw { |     fn from(val: &'a str) -> Raw { | ||||||
|         Raw(Lines::One(Line::Static(val.as_bytes()))) |         Raw::from(val.as_bytes()) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| impl From<&'static [u8]> for Raw { | impl<'a> From<&'a [u8]> for Raw { | ||||||
|     fn from(val: &'static [u8]) -> Raw { |     fn from(val: &'a [u8]) -> Raw { | ||||||
|         Raw(Lines::One(Line::Static(val))) |         Raw(Lines::One(maybe_literal(val.into()))) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user