refactor(header): remove deprecated Header to_string APIs
BREAKING CHANGE: This removes several deprecated methods for converting Headers into strings. Use more specialized methods instead.
This commit is contained in:
		| @@ -86,17 +86,17 @@ impl fmt::Display for PreferenceApplied { | |||||||
|  |  | ||||||
| #[cfg(test)] | #[cfg(test)] | ||||||
| mod tests { | mod tests { | ||||||
|     use header::{Header, Preference}; |     use header::Preference; | ||||||
|     use super::*; |     use super::*; | ||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|     fn test_format_ignore_parameters() { |     fn test_format_ignore_parameters() { | ||||||
|         assert_eq!( |         assert_eq!( | ||||||
|             format!("{}", &PreferenceApplied(vec![Preference::Extension( |             format!("{}", PreferenceApplied(vec![Preference::Extension( | ||||||
|                 "foo".to_owned(), |                 "foo".to_owned(), | ||||||
|                 "bar".to_owned(), |                 "bar".to_owned(), | ||||||
|                 vec![("bar".to_owned(), "foo".to_owned()), ("buz".to_owned(), "".to_owned())] |                 vec![("bar".to_owned(), "foo".to_owned()), ("buz".to_owned(), "".to_owned())] | ||||||
|             )]) as &(Header + Send + Sync)), |             )])), | ||||||
|             "foo=bar".to_owned() |             "foo=bar".to_owned() | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ use std::fmt; | |||||||
| use std::str::from_utf8; | use std::str::from_utf8; | ||||||
|  |  | ||||||
| use super::cell::{OptCell, PtrMapCell}; | use super::cell::{OptCell, PtrMapCell}; | ||||||
| use header::{Header, MultilineFormatter, Raw}; | use header::{Header, MultilineFormatter, Multi, raw, Raw}; | ||||||
|  |  | ||||||
|  |  | ||||||
| #[derive(Clone)] | #[derive(Clone)] | ||||||
| @@ -46,7 +46,8 @@ impl Item { | |||||||
|             return raw; |             return raw; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         let raw = unsafe { self.typed.one() }.to_string().into_bytes().into(); |         let mut raw = raw::new(); | ||||||
|  |         self.write_h1(&mut MultilineFormatter(Multi::Raw(&mut raw))).expect("fmt failed"); | ||||||
|         self.raw.set(raw); |         self.raw.set(raw); | ||||||
|  |  | ||||||
|         self.raw.as_ref().unwrap() |         self.raw.as_ref().unwrap() | ||||||
|   | |||||||
| @@ -167,6 +167,7 @@ pub struct MultilineFormatter<'a, 'b: 'a>(Multi<'a, 'b>); | |||||||
| enum Multi<'a, 'b: 'a> { | enum Multi<'a, 'b: 'a> { | ||||||
|     Line(&'a str, &'a mut fmt::Formatter<'b>), |     Line(&'a str, &'a mut fmt::Formatter<'b>), | ||||||
|     Join(bool, &'a mut fmt::Formatter<'b>), |     Join(bool, &'a mut fmt::Formatter<'b>), | ||||||
|  |     Raw(&'a mut Raw), | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<'a, 'b> MultilineFormatter<'a, 'b> { | impl<'a, 'b> MultilineFormatter<'a, 'b> { | ||||||
| @@ -187,6 +188,12 @@ impl<'a, 'b> MultilineFormatter<'a, 'b> { | |||||||
|                 } |                 } | ||||||
|                 write!(NewlineReplacer(*f), "{}", line) |                 write!(NewlineReplacer(*f), "{}", line) | ||||||
|             } |             } | ||||||
|  |             Multi::Raw(ref mut raw) => { | ||||||
|  |                 let mut s = String::new(); | ||||||
|  |                 try!(write!(NewlineReplacer(&mut s), "{}", line)); | ||||||
|  |                 raw.push(s); | ||||||
|  |                 Ok(()) | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -227,9 +234,9 @@ impl<'a, H: Header> fmt::Debug for HeaderValueString<'a, H> { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| struct NewlineReplacer<'a, 'b: 'a>(&'a mut fmt::Formatter<'b>); | struct NewlineReplacer<'a, F: fmt::Write + 'a>(&'a mut F); | ||||||
|  |  | ||||||
| impl<'a, 'b> fmt::Write for NewlineReplacer<'a, 'b> { | impl<'a, F: fmt::Write + 'a> fmt::Write for NewlineReplacer<'a, F> { | ||||||
|     fn write_str(&mut self, s: &str) -> fmt::Result { |     fn write_str(&mut self, s: &str) -> fmt::Result { | ||||||
|         let mut since = 0; |         let mut since = 0; | ||||||
|         for (i, &byte) in s.as_bytes().iter().enumerate() { |         for (i, &byte) in s.as_bytes().iter().enumerate() { | ||||||
| @@ -643,45 +650,6 @@ impl<'a> FromIterator<HeaderView<'a>> for Headers { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| deprecated! { |  | ||||||
|     #[deprecated(note="The semantics of formatting a HeaderFormat directly are not clear")] |  | ||||||
|     impl<'a> fmt::Display for &'a (Header + Send + Sync) { |  | ||||||
|         #[inline] |  | ||||||
|         fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |  | ||||||
|             let mut multi = MultilineFormatter(Multi::Join(true, f)); |  | ||||||
|             self.fmt_multi_header(&mut multi) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| deprecated! { |  | ||||||
|     #[deprecated(note="The semantics of formatting a HeaderFormat directly are not clear")] |  | ||||||
|     /// A wrapper around any Header with a Display impl that calls `fmt_header`. |  | ||||||
|     /// |  | ||||||
|     /// This can be used like so: `format!("{}", HeaderFormatter(&header))` to |  | ||||||
|     /// get the 'value string' representation of this Header. |  | ||||||
|     /// |  | ||||||
|     /// Note: This may not necessarily be the value written to stream, such |  | ||||||
|     /// as with the SetCookie header. |  | ||||||
|     pub struct HeaderFormatter<'a, H: Header>(pub &'a H); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[allow(deprecated)] |  | ||||||
| impl<'a, H: Header> fmt::Display for HeaderFormatter<'a, H> { |  | ||||||
|     #[inline] |  | ||||||
|     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |  | ||||||
|         fmt::Debug::fmt(&HeaderValueString(self.0), f) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[allow(deprecated)] |  | ||||||
| impl<'a, H: Header> fmt::Debug for HeaderFormatter<'a, H> { |  | ||||||
|     #[inline] |  | ||||||
|     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |  | ||||||
|         fmt::Display::fmt(self, f) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Clone, Debug)] | #[derive(Clone, Debug)] | ||||||
| struct HeaderName(UniCase<Cow<'static, str>>); | struct HeaderName(UniCase<Cow<'static, str>>); | ||||||
|  |  | ||||||
| @@ -717,7 +685,7 @@ mod tests { | |||||||
|     use mime::TopLevel::Text; |     use mime::TopLevel::Text; | ||||||
|     use mime::SubLevel::Plain; |     use mime::SubLevel::Plain; | ||||||
|     use super::{Headers, Header, Raw, ContentLength, ContentType, |     use super::{Headers, Header, Raw, ContentLength, ContentType, | ||||||
|                 Accept, Host, qitem}; |                 Accept, Host, qitem, SetCookie}; | ||||||
|  |  | ||||||
|     #[cfg(feature = "nightly")] |     #[cfg(feature = "nightly")] | ||||||
|     use test::Bencher; |     use test::Bencher; | ||||||
| @@ -814,6 +782,19 @@ mod tests { | |||||||
|         let ContentType(_) = *headers.get::<ContentType>().unwrap(); |         let ContentType(_) = *headers.get::<ContentType>().unwrap(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     #[test] | ||||||
|  |     fn test_typed_get_raw() { | ||||||
|  |         let mut headers = Headers::new(); | ||||||
|  |         headers.set(ContentLength(15)); | ||||||
|  |         assert_eq!(headers.get_raw("content-length").unwrap(), "15"); | ||||||
|  |  | ||||||
|  |         headers.set(SetCookie(vec![ | ||||||
|  |             "foo=bar".to_string(), | ||||||
|  |             "baz=quux; Path=/path".to_string() | ||||||
|  |         ])); | ||||||
|  |         assert_eq!(headers.get_raw("set-cookie").unwrap(), &["foo=bar", "baz=quux; Path=/path"][..]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|     fn test_get_mutable() { |     fn test_get_mutable() { | ||||||
|         let mut headers = make_header!(b"Content-Length: 10"); |         let mut headers = make_header!(b"Content-Length: 10"); | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ use std::fmt; | |||||||
| use bytes::Bytes; | use bytes::Bytes; | ||||||
|  |  | ||||||
| /// A raw header value. | /// A raw header value. | ||||||
| #[derive(Clone, PartialEq, Eq)] | #[derive(Clone, Debug)] | ||||||
| pub struct Raw(Lines); | pub struct Raw(Lines); | ||||||
|  |  | ||||||
| impl Raw { | impl Raw { | ||||||
| @@ -11,6 +11,7 @@ impl Raw { | |||||||
|     #[inline] |     #[inline] | ||||||
|     pub fn len(&self) -> usize { |     pub fn len(&self) -> usize { | ||||||
|         match self.0 { |         match self.0 { | ||||||
|  |             Lines::Empty => 0, | ||||||
|             Lines::One(..) => 1, |             Lines::One(..) => 1, | ||||||
|             Lines::Many(ref lines) => lines.len() |             Lines::Many(ref lines) => lines.len() | ||||||
|         } |         } | ||||||
| @@ -39,6 +40,7 @@ impl Raw { | |||||||
|     pub fn push<V: Into<Raw>>(&mut self, val: V) { |     pub fn push<V: Into<Raw>>(&mut self, val: V) { | ||||||
|         let raw = val.into(); |         let raw = val.into(); | ||||||
|         match raw.0 { |         match raw.0 { | ||||||
|  |             Lines::Empty => (), | ||||||
|             Lines::One(one) => self.push_line(one), |             Lines::One(one) => self.push_line(one), | ||||||
|             Lines::Many(lines) => { |             Lines::Many(lines) => { | ||||||
|                 for line in lines { |                 for line in lines { | ||||||
| @@ -48,9 +50,12 @@ impl Raw { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fn push_line(&mut self, line: Line) { |     fn push_line(&mut self, line: Bytes) { | ||||||
|         let lines = ::std::mem::replace(&mut self.0, Lines::Many(Vec::new())); |         let lines = ::std::mem::replace(&mut self.0, Lines::Empty); | ||||||
|         match lines { |         match lines { | ||||||
|  |             Lines::Empty => { | ||||||
|  |                 self.0 = Lines::One(line); | ||||||
|  |             } | ||||||
|             Lines::One(one) => { |             Lines::One(one) => { | ||||||
|                 self.0 = Lines::Many(vec![one, line]); |                 self.0 = Lines::Many(vec![one, line]); | ||||||
|             } |             } | ||||||
| @@ -62,20 +67,14 @@ impl Raw { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Clone, PartialEq, Eq)] | #[derive(Clone)] | ||||||
| enum Lines { | enum Lines { | ||||||
|     One(Line), |     Empty, | ||||||
|     Many(Vec<Line>), |     One(Bytes), | ||||||
|  |     Many(Vec<Bytes>), | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Clone, PartialEq, Eq)] | fn eq_many<A: AsRef<[u8]>, B: AsRef<[u8]>>(a: &[A], b: &[B]) -> bool { | ||||||
| enum Line { |  | ||||||
|     Static(&'static [u8]), |  | ||||||
|     Owned(Vec<u8>), |  | ||||||
|     Shared(Bytes), |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn eq<A: AsRef<[u8]>, B: AsRef<[u8]>>(a: &[A], b: &[B]) -> bool { |  | ||||||
|     if a.len() != b.len() { |     if a.len() != b.len() { | ||||||
|         false |         false | ||||||
|     } else { |     } else { | ||||||
| @@ -88,18 +87,54 @@ fn eq<A: AsRef<[u8]>, B: AsRef<[u8]>>(a: &[A], b: &[B]) -> bool { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | fn eq<B: AsRef<[u8]>>(raw: &Raw, b: &[B]) -> bool { | ||||||
|  |     match raw.0 { | ||||||
|  |         Lines::Empty => b.is_empty(), | ||||||
|  |         Lines::One(ref line) => eq_many(&[line], b), | ||||||
|  |         Lines::Many(ref lines) => eq_many(lines, b) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl PartialEq for Raw { | ||||||
|  |     fn eq(&self, other: &Raw) -> bool { | ||||||
|  |         match other.0 { | ||||||
|  |             Lines::Empty => eq(self, &[] as &[Bytes]), | ||||||
|  |             Lines::One(ref line) => eq(self, &[line]), | ||||||
|  |             Lines::Many(ref lines) => eq(self, lines), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl Eq for Raw {} | ||||||
|  |  | ||||||
| impl PartialEq<[Vec<u8>]> for Raw { | impl PartialEq<[Vec<u8>]> for Raw { | ||||||
|     fn eq(&self, bytes: &[Vec<u8>]) -> bool { |     fn eq(&self, bytes: &[Vec<u8>]) -> bool { | ||||||
|         match self.0 { |         eq(self, bytes) | ||||||
|             Lines::One(ref line) => eq(&[line], bytes), |  | ||||||
|             Lines::Many(ref lines) => eq(lines, bytes) |  | ||||||
|     } |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl<'a> PartialEq<[&'a [u8]]> for Raw { | ||||||
|  |     fn eq(&self, bytes: &[&[u8]]) -> bool { | ||||||
|  |         eq(self, bytes) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl PartialEq<[String]> for Raw { | ||||||
|  |     fn eq(&self, bytes: &[String]) -> bool { | ||||||
|  |         eq(self, bytes) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl<'a> PartialEq<[&'a str]> for Raw { | ||||||
|  |     fn eq(&self, bytes: &[&'a str]) -> bool { | ||||||
|  |         eq(self, bytes) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| impl PartialEq<[u8]> for Raw { | impl PartialEq<[u8]> for Raw { | ||||||
|     fn eq(&self, bytes: &[u8]) -> bool { |     fn eq(&self, bytes: &[u8]) -> bool { | ||||||
|         match self.0 { |         match self.0 { | ||||||
|  |             Lines::Empty => bytes.is_empty(), | ||||||
|             Lines::One(ref line) => line.as_ref() == bytes, |             Lines::One(ref line) => line.as_ref() == bytes, | ||||||
|             Lines::Many(..) => false |             Lines::Many(..) => false | ||||||
|         } |         } | ||||||
| @@ -108,10 +143,7 @@ impl PartialEq<[u8]> for Raw { | |||||||
|  |  | ||||||
| impl PartialEq<str> for Raw { | impl PartialEq<str> for Raw { | ||||||
|     fn eq(&self, s: &str) -> bool { |     fn eq(&self, s: &str) -> bool { | ||||||
|         match self.0 { |         self == s.as_bytes() | ||||||
|             Lines::One(ref line) => line.as_ref() == s.as_bytes(), |  | ||||||
|             Lines::Many(..) => false |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -155,31 +187,7 @@ impl<'a> From<&'a [u8]> for Raw { | |||||||
| impl From<Bytes> for Raw { | impl From<Bytes> for Raw { | ||||||
|     #[inline] |     #[inline] | ||||||
|     fn from(val: Bytes) -> Raw { |     fn from(val: Bytes) -> Raw { | ||||||
|         Raw(Lines::One(Line::Shared(val))) |         Raw(Lines::One(val)) | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl From<Vec<u8>> for Line { |  | ||||||
|     #[inline] |  | ||||||
|     fn from(val: Vec<u8>) -> Line { |  | ||||||
|         Line::Owned(val) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl From<Bytes> for Line { |  | ||||||
|     #[inline] |  | ||||||
|     fn from(val: Bytes) -> Line { |  | ||||||
|         Line::Shared(val) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl AsRef<[u8]> for Line { |  | ||||||
|     fn as_ref(&self) -> &[u8] { |  | ||||||
|         match *self { |  | ||||||
|             Line::Static(ref s) => s, |  | ||||||
|             Line::Owned(ref v) => v.as_ref(), |  | ||||||
|             Line::Shared(ref m) => m.as_ref(), |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -188,12 +196,17 @@ pub fn parsed(val: Bytes) -> Raw { | |||||||
| } | } | ||||||
|  |  | ||||||
| pub fn push(raw: &mut Raw, val: Bytes) { | pub fn push(raw: &mut Raw, val: Bytes) { | ||||||
|     raw.push_line(Line::from(val)); |     raw.push_line(val); | ||||||
| } | } | ||||||
|  |  | ||||||
| impl fmt::Debug for Raw { | pub fn new() -> Raw { | ||||||
|  |     Raw(Lines::Empty) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl fmt::Debug for Lines { | ||||||
|     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||||
|         match self.0 { |         match *self { | ||||||
|  |             Lines::Empty => f.pad("[]"), | ||||||
|             Lines::One(ref line) => fmt::Debug::fmt(&[line], f), |             Lines::One(ref line) => fmt::Debug::fmt(&[line], f), | ||||||
|             Lines::Many(ref lines) => fmt::Debug::fmt(lines, f) |             Lines::Many(ref lines) => fmt::Debug::fmt(lines, f) | ||||||
|         } |         } | ||||||
| @@ -205,6 +218,7 @@ impl ::std::ops::Index<usize> for Raw { | |||||||
|  |  | ||||||
|     fn index(&self, idx: usize) -> &[u8] { |     fn index(&self, idx: usize) -> &[u8] { | ||||||
|         match self.0 { |         match self.0 { | ||||||
|  |             Lines::Empty => panic!("index of out of bounds: {}", idx), | ||||||
|             Lines::One(ref line) => if idx == 0 { |             Lines::One(ref line) => if idx == 0 { | ||||||
|                 line.as_ref() |                 line.as_ref() | ||||||
|             } else { |             } else { | ||||||
| @@ -217,12 +231,12 @@ impl ::std::ops::Index<usize> for Raw { | |||||||
|  |  | ||||||
| macro_rules! literals { | macro_rules! literals { | ||||||
|     ($($len:expr => $($value:expr),+;)+) => ( |     ($($len:expr => $($value:expr),+;)+) => ( | ||||||
|         fn maybe_literal<'a>(s: Cow<'a, [u8]>) -> Line { |         fn maybe_literal<'a>(s: Cow<'a, [u8]>) -> Bytes { | ||||||
|             match s.len() { |             match s.len() { | ||||||
|                 $($len => { |                 $($len => { | ||||||
|                     $( |                     $( | ||||||
|                     if s.as_ref() == $value { |                     if s.as_ref() == $value { | ||||||
|                         return Line::Static($value); |                         return Bytes::from_static($value); | ||||||
|                     } |                     } | ||||||
|                     )+ |                     )+ | ||||||
|                 })+ |                 })+ | ||||||
| @@ -230,7 +244,7 @@ macro_rules! literals { | |||||||
|                 _ => () |                 _ => () | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             Line::from(s.into_owned()) |             Bytes::from(s.into_owned()) | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         #[test] |         #[test] | ||||||
| @@ -263,12 +277,19 @@ impl<'a> IntoIterator for &'a Raw { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug)] |  | ||||||
| pub struct RawLines<'a> { | pub struct RawLines<'a> { | ||||||
|     inner: &'a Lines, |     inner: &'a Lines, | ||||||
|     pos: usize, |     pos: usize, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | impl<'a> fmt::Debug for RawLines<'a> { | ||||||
|  |     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||||
|  |         f.debug_tuple("RawLines") | ||||||
|  |             .field(&self.inner) | ||||||
|  |             .finish() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| impl<'a> Iterator for RawLines<'a> { | impl<'a> Iterator for RawLines<'a> { | ||||||
|     type Item = &'a [u8]; |     type Item = &'a [u8]; | ||||||
|  |  | ||||||
| @@ -277,6 +298,7 @@ impl<'a> Iterator for RawLines<'a> { | |||||||
|         let current_pos = self.pos; |         let current_pos = self.pos; | ||||||
|         self.pos += 1; |         self.pos += 1; | ||||||
|         match *self.inner { |         match *self.inner { | ||||||
|  |             Lines::Empty => None, | ||||||
|             Lines::One(ref line) => { |             Lines::One(ref line) => { | ||||||
|                 if current_pos == 0 { |                 if current_pos == 0 { | ||||||
|                     Some(line.as_ref()) |                     Some(line.as_ref()) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user