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