Skip to content

Commit

Permalink
refactor(header): remove deprecated Header to_string APIs
Browse files Browse the repository at this point in the history
BREAKING CHANGE: This removes several deprecated methods for converting
  Headers into strings. Use more specialized methods instead.
  • Loading branch information
seanmonstar committed Mar 21, 2017
1 parent 4f69788 commit ec91bf4
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 101 deletions.
6 changes: 3 additions & 3 deletions src/header/common/preference_applied.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,17 @@ impl fmt::Display for PreferenceApplied {

#[cfg(test)]
mod tests {
use header::{Header, Preference};
use header::Preference;
use super::*;

#[test]
fn test_format_ignore_parameters() {
assert_eq!(
format!("{}", &PreferenceApplied(vec![Preference::Extension(
format!("{}", PreferenceApplied(vec![Preference::Extension(
"foo".to_owned(),
"bar".to_owned(),
vec![("bar".to_owned(), "foo".to_owned()), ("buz".to_owned(), "".to_owned())]
)]) as &(Header + Send + Sync)),
)])),
"foo=bar".to_owned()
);
}
Expand Down
5 changes: 3 additions & 2 deletions src/header/internals/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::fmt;
use std::str::from_utf8;

use super::cell::{OptCell, PtrMapCell};
use header::{Header, MultilineFormatter, Raw};
use header::{Header, MultilineFormatter, Multi, raw, Raw};


#[derive(Clone)]
Expand Down Expand Up @@ -46,7 +46,8 @@ impl Item {
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.as_ref().unwrap()
Expand Down
65 changes: 23 additions & 42 deletions src/header/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ pub struct MultilineFormatter<'a, 'b: 'a>(Multi<'a, 'b>);
enum Multi<'a, 'b: 'a> {
Line(&'a str, &'a mut fmt::Formatter<'b>),
Join(bool, &'a mut fmt::Formatter<'b>),
Raw(&'a mut Raw),
}

impl<'a, 'b> MultilineFormatter<'a, 'b> {
Expand All @@ -187,6 +188,12 @@ impl<'a, 'b> MultilineFormatter<'a, 'b> {
}
write!(NewlineReplacer(*f), "{}", line)
}
Multi::Raw(ref mut raw) => {
let mut s = String::new();
try!(write!(NewlineReplacer(&mut s), "{}", line));
raw.push(s);
Ok(())
}
}
}
}
Expand Down Expand Up @@ -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 {
let mut since = 0;
for (i, &byte) in s.as_bytes().iter().enumerate() {
Expand Down Expand Up @@ -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)]
struct HeaderName(UniCase<Cow<'static, str>>);

Expand Down Expand Up @@ -717,7 +685,7 @@ mod tests {
use mime::TopLevel::Text;
use mime::SubLevel::Plain;
use super::{Headers, Header, Raw, ContentLength, ContentType,
Accept, Host, qitem};
Accept, Host, qitem, SetCookie};

#[cfg(feature = "nightly")]
use test::Bencher;
Expand Down Expand Up @@ -814,6 +782,19 @@ mod tests {
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]
fn test_get_mutable() {
let mut headers = make_header!(b"Content-Length: 10");
Expand Down
130 changes: 76 additions & 54 deletions src/header/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ use std::fmt;
use bytes::Bytes;

/// A raw header value.
#[derive(Clone, PartialEq, Eq)]
#[derive(Clone, Debug)]
pub struct Raw(Lines);

impl Raw {
/// Returns the amount of lines.
#[inline]
pub fn len(&self) -> usize {
match self.0 {
Lines::Empty => 0,
Lines::One(..) => 1,
Lines::Many(ref lines) => lines.len()
}
Expand Down Expand Up @@ -39,6 +40,7 @@ impl Raw {
pub fn push<V: Into<Raw>>(&mut self, val: V) {
let raw = val.into();
match raw.0 {
Lines::Empty => (),
Lines::One(one) => self.push_line(one),
Lines::Many(lines) => {
for line in lines {
Expand All @@ -48,9 +50,12 @@ impl Raw {
}
}

fn push_line(&mut self, line: Line) {
let lines = ::std::mem::replace(&mut self.0, Lines::Many(Vec::new()));
fn push_line(&mut self, line: Bytes) {
let lines = ::std::mem::replace(&mut self.0, Lines::Empty);
match lines {
Lines::Empty => {
self.0 = Lines::One(line);
}
Lines::One(one) => {
self.0 = Lines::Many(vec![one, line]);
}
Expand All @@ -62,20 +67,14 @@ impl Raw {
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Clone)]
enum Lines {
One(Line),
Many(Vec<Line>),
}

#[derive(Debug, Clone, PartialEq, Eq)]
enum Line {
Static(&'static [u8]),
Owned(Vec<u8>),
Shared(Bytes),
Empty,
One(Bytes),
Many(Vec<Bytes>),
}

fn eq<A: AsRef<[u8]>, B: AsRef<[u8]>>(a: &[A], b: &[B]) -> bool {
fn eq_many<A: AsRef<[u8]>, B: AsRef<[u8]>>(a: &[A], b: &[B]) -> bool {
if a.len() != b.len() {
false
} else {
Expand All @@ -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 {
fn eq(&self, bytes: &[Vec<u8>]) -> bool {
match self.0 {
Lines::One(ref line) => eq(&[line], bytes),
Lines::Many(ref lines) => eq(lines, bytes)
}
eq(self, 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 {
fn eq(&self, bytes: &[u8]) -> bool {
match self.0 {
Lines::Empty => bytes.is_empty(),
Lines::One(ref line) => line.as_ref() == bytes,
Lines::Many(..) => false
}
Expand All @@ -108,10 +143,7 @@ impl PartialEq<[u8]> for Raw {

impl PartialEq<str> for Raw {
fn eq(&self, s: &str) -> bool {
match self.0 {
Lines::One(ref line) => line.as_ref() == s.as_bytes(),
Lines::Many(..) => false
}
self == s.as_bytes()
}
}

Expand Down Expand Up @@ -155,31 +187,7 @@ impl<'a> From<&'a [u8]> for Raw {
impl From<Bytes> for Raw {
#[inline]
fn from(val: Bytes) -> Raw {
Raw(Lines::One(Line::Shared(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(),
}
Raw(Lines::One(val))
}
}

Expand All @@ -188,12 +196,17 @@ pub fn parsed(val: Bytes) -> Raw {
}

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 {
match self.0 {
match *self {
Lines::Empty => f.pad("[]"),
Lines::One(ref line) => fmt::Debug::fmt(&[line], f),
Lines::Many(ref lines) => fmt::Debug::fmt(lines, f)
}
Expand All @@ -205,6 +218,7 @@ impl ::std::ops::Index<usize> for Raw {

fn index(&self, idx: usize) -> &[u8] {
match self.0 {
Lines::Empty => panic!("index of out of bounds: {}", idx),
Lines::One(ref line) => if idx == 0 {
line.as_ref()
} else {
Expand All @@ -217,20 +231,20 @@ impl ::std::ops::Index<usize> for Raw {

macro_rules! literals {
($($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() {
$($len => {
$(
if s.as_ref() == $value {
return Line::Static($value);
return Bytes::from_static($value);
}
)+
})+

_ => ()
}

Line::from(s.into_owned())
Bytes::from(s.into_owned())
}

#[test]
Expand Down Expand Up @@ -263,12 +277,19 @@ impl<'a> IntoIterator for &'a Raw {
}
}

#[derive(Debug)]
pub struct RawLines<'a> {
inner: &'a Lines,
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> {
type Item = &'a [u8];

Expand All @@ -277,6 +298,7 @@ impl<'a> Iterator for RawLines<'a> {
let current_pos = self.pos;
self.pos += 1;
match *self.inner {
Lines::Empty => None,
Lines::One(ref line) => {
if current_pos == 0 {
Some(line.as_ref())
Expand Down

0 comments on commit ec91bf4

Please sign in to comment.