Skip to content

Commit ec91bf4

Browse files
committed
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.
1 parent 4f69788 commit ec91bf4

File tree

4 files changed

+105
-101
lines changed

4 files changed

+105
-101
lines changed

src/header/common/preference_applied.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -86,17 +86,17 @@ impl fmt::Display for PreferenceApplied {
8686

8787
#[cfg(test)]
8888
mod tests {
89-
use header::{Header, Preference};
89+
use header::Preference;
9090
use super::*;
9191

9292
#[test]
9393
fn test_format_ignore_parameters() {
9494
assert_eq!(
95-
format!("{}", &PreferenceApplied(vec![Preference::Extension(
95+
format!("{}", PreferenceApplied(vec![Preference::Extension(
9696
"foo".to_owned(),
9797
"bar".to_owned(),
9898
vec![("bar".to_owned(), "foo".to_owned()), ("buz".to_owned(), "".to_owned())]
99-
)]) as &(Header + Send + Sync)),
99+
)])),
100100
"foo=bar".to_owned()
101101
);
102102
}

src/header/internals/item.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::fmt;
44
use std::str::from_utf8;
55

66
use super::cell::{OptCell, PtrMapCell};
7-
use header::{Header, MultilineFormatter, Raw};
7+
use header::{Header, MultilineFormatter, Multi, raw, Raw};
88

99

1010
#[derive(Clone)]
@@ -46,7 +46,8 @@ impl Item {
4646
return raw;
4747
}
4848

49-
let raw = unsafe { self.typed.one() }.to_string().into_bytes().into();
49+
let mut raw = raw::new();
50+
self.write_h1(&mut MultilineFormatter(Multi::Raw(&mut raw))).expect("fmt failed");
5051
self.raw.set(raw);
5152

5253
self.raw.as_ref().unwrap()

src/header/mod.rs

+23-42
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ pub struct MultilineFormatter<'a, 'b: 'a>(Multi<'a, 'b>);
167167
enum Multi<'a, 'b: 'a> {
168168
Line(&'a str, &'a mut fmt::Formatter<'b>),
169169
Join(bool, &'a mut fmt::Formatter<'b>),
170+
Raw(&'a mut Raw),
170171
}
171172

172173
impl<'a, 'b> MultilineFormatter<'a, 'b> {
@@ -187,6 +188,12 @@ impl<'a, 'b> MultilineFormatter<'a, 'b> {
187188
}
188189
write!(NewlineReplacer(*f), "{}", line)
189190
}
191+
Multi::Raw(ref mut raw) => {
192+
let mut s = String::new();
193+
try!(write!(NewlineReplacer(&mut s), "{}", line));
194+
raw.push(s);
195+
Ok(())
196+
}
190197
}
191198
}
192199
}
@@ -227,9 +234,9 @@ impl<'a, H: Header> fmt::Debug for HeaderValueString<'a, H> {
227234
}
228235
}
229236

230-
struct NewlineReplacer<'a, 'b: 'a>(&'a mut fmt::Formatter<'b>);
237+
struct NewlineReplacer<'a, F: fmt::Write + 'a>(&'a mut F);
231238

232-
impl<'a, 'b> fmt::Write for NewlineReplacer<'a, 'b> {
239+
impl<'a, F: fmt::Write + 'a> fmt::Write for NewlineReplacer<'a, F> {
233240
fn write_str(&mut self, s: &str) -> fmt::Result {
234241
let mut since = 0;
235242
for (i, &byte) in s.as_bytes().iter().enumerate() {
@@ -643,45 +650,6 @@ impl<'a> FromIterator<HeaderView<'a>> for Headers {
643650
}
644651
}
645652

646-
deprecated! {
647-
#[deprecated(note="The semantics of formatting a HeaderFormat directly are not clear")]
648-
impl<'a> fmt::Display for &'a (Header + Send + Sync) {
649-
#[inline]
650-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
651-
let mut multi = MultilineFormatter(Multi::Join(true, f));
652-
self.fmt_multi_header(&mut multi)
653-
}
654-
}
655-
}
656-
657-
deprecated! {
658-
#[deprecated(note="The semantics of formatting a HeaderFormat directly are not clear")]
659-
/// A wrapper around any Header with a Display impl that calls `fmt_header`.
660-
///
661-
/// This can be used like so: `format!("{}", HeaderFormatter(&header))` to
662-
/// get the 'value string' representation of this Header.
663-
///
664-
/// Note: This may not necessarily be the value written to stream, such
665-
/// as with the SetCookie header.
666-
pub struct HeaderFormatter<'a, H: Header>(pub &'a H);
667-
}
668-
669-
#[allow(deprecated)]
670-
impl<'a, H: Header> fmt::Display for HeaderFormatter<'a, H> {
671-
#[inline]
672-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
673-
fmt::Debug::fmt(&HeaderValueString(self.0), f)
674-
}
675-
}
676-
677-
#[allow(deprecated)]
678-
impl<'a, H: Header> fmt::Debug for HeaderFormatter<'a, H> {
679-
#[inline]
680-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
681-
fmt::Display::fmt(self, f)
682-
}
683-
}
684-
685653
#[derive(Clone, Debug)]
686654
struct HeaderName(UniCase<Cow<'static, str>>);
687655

@@ -717,7 +685,7 @@ mod tests {
717685
use mime::TopLevel::Text;
718686
use mime::SubLevel::Plain;
719687
use super::{Headers, Header, Raw, ContentLength, ContentType,
720-
Accept, Host, qitem};
688+
Accept, Host, qitem, SetCookie};
721689

722690
#[cfg(feature = "nightly")]
723691
use test::Bencher;
@@ -814,6 +782,19 @@ mod tests {
814782
let ContentType(_) = *headers.get::<ContentType>().unwrap();
815783
}
816784

785+
#[test]
786+
fn test_typed_get_raw() {
787+
let mut headers = Headers::new();
788+
headers.set(ContentLength(15));
789+
assert_eq!(headers.get_raw("content-length").unwrap(), "15");
790+
791+
headers.set(SetCookie(vec![
792+
"foo=bar".to_string(),
793+
"baz=quux; Path=/path".to_string()
794+
]));
795+
assert_eq!(headers.get_raw("set-cookie").unwrap(), &["foo=bar", "baz=quux; Path=/path"][..]);
796+
}
797+
817798
#[test]
818799
fn test_get_mutable() {
819800
let mut headers = make_header!(b"Content-Length: 10");

src/header/raw.rs

+76-54
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ use std::fmt;
33
use bytes::Bytes;
44

55
/// A raw header value.
6-
#[derive(Clone, PartialEq, Eq)]
6+
#[derive(Clone, Debug)]
77
pub struct Raw(Lines);
88

99
impl Raw {
1010
/// Returns the amount of lines.
1111
#[inline]
1212
pub fn len(&self) -> usize {
1313
match self.0 {
14+
Lines::Empty => 0,
1415
Lines::One(..) => 1,
1516
Lines::Many(ref lines) => lines.len()
1617
}
@@ -39,6 +40,7 @@ impl Raw {
3940
pub fn push<V: Into<Raw>>(&mut self, val: V) {
4041
let raw = val.into();
4142
match raw.0 {
43+
Lines::Empty => (),
4244
Lines::One(one) => self.push_line(one),
4345
Lines::Many(lines) => {
4446
for line in lines {
@@ -48,9 +50,12 @@ impl Raw {
4850
}
4951
}
5052

51-
fn push_line(&mut self, line: Line) {
52-
let lines = ::std::mem::replace(&mut self.0, Lines::Many(Vec::new()));
53+
fn push_line(&mut self, line: Bytes) {
54+
let lines = ::std::mem::replace(&mut self.0, Lines::Empty);
5355
match lines {
56+
Lines::Empty => {
57+
self.0 = Lines::One(line);
58+
}
5459
Lines::One(one) => {
5560
self.0 = Lines::Many(vec![one, line]);
5661
}
@@ -62,20 +67,14 @@ impl Raw {
6267
}
6368
}
6469

65-
#[derive(Debug, Clone, PartialEq, Eq)]
70+
#[derive(Clone)]
6671
enum Lines {
67-
One(Line),
68-
Many(Vec<Line>),
69-
}
70-
71-
#[derive(Debug, Clone, PartialEq, Eq)]
72-
enum Line {
73-
Static(&'static [u8]),
74-
Owned(Vec<u8>),
75-
Shared(Bytes),
72+
Empty,
73+
One(Bytes),
74+
Many(Vec<Bytes>),
7675
}
7776

78-
fn eq<A: AsRef<[u8]>, B: AsRef<[u8]>>(a: &[A], b: &[B]) -> bool {
77+
fn eq_many<A: AsRef<[u8]>, B: AsRef<[u8]>>(a: &[A], b: &[B]) -> bool {
7978
if a.len() != b.len() {
8079
false
8180
} else {
@@ -88,18 +87,54 @@ fn eq<A: AsRef<[u8]>, B: AsRef<[u8]>>(a: &[A], b: &[B]) -> bool {
8887
}
8988
}
9089

90+
fn eq<B: AsRef<[u8]>>(raw: &Raw, b: &[B]) -> bool {
91+
match raw.0 {
92+
Lines::Empty => b.is_empty(),
93+
Lines::One(ref line) => eq_many(&[line], b),
94+
Lines::Many(ref lines) => eq_many(lines, b)
95+
}
96+
}
97+
98+
impl PartialEq for Raw {
99+
fn eq(&self, other: &Raw) -> bool {
100+
match other.0 {
101+
Lines::Empty => eq(self, &[] as &[Bytes]),
102+
Lines::One(ref line) => eq(self, &[line]),
103+
Lines::Many(ref lines) => eq(self, lines),
104+
}
105+
}
106+
}
107+
108+
impl Eq for Raw {}
109+
91110
impl PartialEq<[Vec<u8>]> for Raw {
92111
fn eq(&self, bytes: &[Vec<u8>]) -> bool {
93-
match self.0 {
94-
Lines::One(ref line) => eq(&[line], bytes),
95-
Lines::Many(ref lines) => eq(lines, bytes)
96-
}
112+
eq(self, bytes)
113+
}
114+
}
115+
116+
impl<'a> PartialEq<[&'a [u8]]> for Raw {
117+
fn eq(&self, bytes: &[&[u8]]) -> bool {
118+
eq(self, bytes)
119+
}
120+
}
121+
122+
impl PartialEq<[String]> for Raw {
123+
fn eq(&self, bytes: &[String]) -> bool {
124+
eq(self, bytes)
125+
}
126+
}
127+
128+
impl<'a> PartialEq<[&'a str]> for Raw {
129+
fn eq(&self, bytes: &[&'a str]) -> bool {
130+
eq(self, bytes)
97131
}
98132
}
99133

100134
impl PartialEq<[u8]> for Raw {
101135
fn eq(&self, bytes: &[u8]) -> bool {
102136
match self.0 {
137+
Lines::Empty => bytes.is_empty(),
103138
Lines::One(ref line) => line.as_ref() == bytes,
104139
Lines::Many(..) => false
105140
}
@@ -108,10 +143,7 @@ impl PartialEq<[u8]> for Raw {
108143

109144
impl PartialEq<str> for Raw {
110145
fn eq(&self, s: &str) -> bool {
111-
match self.0 {
112-
Lines::One(ref line) => line.as_ref() == s.as_bytes(),
113-
Lines::Many(..) => false
114-
}
146+
self == s.as_bytes()
115147
}
116148
}
117149

@@ -155,31 +187,7 @@ impl<'a> From<&'a [u8]> for Raw {
155187
impl From<Bytes> for Raw {
156188
#[inline]
157189
fn from(val: Bytes) -> Raw {
158-
Raw(Lines::One(Line::Shared(val)))
159-
}
160-
}
161-
162-
impl From<Vec<u8>> for Line {
163-
#[inline]
164-
fn from(val: Vec<u8>) -> Line {
165-
Line::Owned(val)
166-
}
167-
}
168-
169-
impl From<Bytes> for Line {
170-
#[inline]
171-
fn from(val: Bytes) -> Line {
172-
Line::Shared(val)
173-
}
174-
}
175-
176-
impl AsRef<[u8]> for Line {
177-
fn as_ref(&self) -> &[u8] {
178-
match *self {
179-
Line::Static(ref s) => s,
180-
Line::Owned(ref v) => v.as_ref(),
181-
Line::Shared(ref m) => m.as_ref(),
182-
}
190+
Raw(Lines::One(val))
183191
}
184192
}
185193

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

190198
pub fn push(raw: &mut Raw, val: Bytes) {
191-
raw.push_line(Line::from(val));
199+
raw.push_line(val);
192200
}
193201

194-
impl fmt::Debug for Raw {
202+
pub fn new() -> Raw {
203+
Raw(Lines::Empty)
204+
}
205+
206+
impl fmt::Debug for Lines {
195207
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
196-
match self.0 {
208+
match *self {
209+
Lines::Empty => f.pad("[]"),
197210
Lines::One(ref line) => fmt::Debug::fmt(&[line], f),
198211
Lines::Many(ref lines) => fmt::Debug::fmt(lines, f)
199212
}
@@ -205,6 +218,7 @@ impl ::std::ops::Index<usize> for Raw {
205218

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

218232
macro_rules! literals {
219233
($($len:expr => $($value:expr),+;)+) => (
220-
fn maybe_literal<'a>(s: Cow<'a, [u8]>) -> Line {
234+
fn maybe_literal<'a>(s: Cow<'a, [u8]>) -> Bytes {
221235
match s.len() {
222236
$($len => {
223237
$(
224238
if s.as_ref() == $value {
225-
return Line::Static($value);
239+
return Bytes::from_static($value);
226240
}
227241
)+
228242
})+
229243

230244
_ => ()
231245
}
232246

233-
Line::from(s.into_owned())
247+
Bytes::from(s.into_owned())
234248
}
235249

236250
#[test]
@@ -263,12 +277,19 @@ impl<'a> IntoIterator for &'a Raw {
263277
}
264278
}
265279

266-
#[derive(Debug)]
267280
pub struct RawLines<'a> {
268281
inner: &'a Lines,
269282
pos: usize,
270283
}
271284

285+
impl<'a> fmt::Debug for RawLines<'a> {
286+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
287+
f.debug_tuple("RawLines")
288+
.field(&self.inner)
289+
.finish()
290+
}
291+
}
292+
272293
impl<'a> Iterator for RawLines<'a> {
273294
type Item = &'a [u8];
274295

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

0 commit comments

Comments
 (0)