hyper_old_types/header/
raw.rs1use std::borrow::Cow;
2use std::fmt;
3use bytes::Bytes;
4
5#[derive(Clone, Debug)]
7pub struct Raw(Lines);
8
9impl Raw {
10 #[inline]
12 pub fn len(&self) -> usize {
13 match self.0 {
14 Lines::Empty => 0,
15 Lines::One(..) => 1,
16 Lines::Many(ref lines) => lines.len()
17 }
18 }
19
20 #[inline]
22 pub fn one(&self) -> Option<&[u8]> {
23 match self.0 {
24 Lines::One(ref line) => Some(line.as_ref()),
25 Lines::Many(ref lines) if lines.len() == 1 => Some(lines[0].as_ref()),
26 _ => None
27 }
28 }
29
30 #[inline]
32 pub fn iter(&self) -> RawLines {
33 RawLines {
34 inner: &self.0,
35 pos: 0,
36 }
37 }
38
39 pub fn push<V: Into<Raw>>(&mut self, val: V) {
41 let raw = val.into();
42 match raw.0 {
43 Lines::Empty => (),
44 Lines::One(one) => self.push_line(one),
45 Lines::Many(lines) => {
46 for line in lines {
47 self.push_line(line);
48 }
49 }
50 }
51 }
52
53 fn push_line(&mut self, line: Bytes) {
54 let lines = ::std::mem::replace(&mut self.0, Lines::Empty);
55 match lines {
56 Lines::Empty => {
57 self.0 = Lines::One(line);
58 }
59 Lines::One(one) => {
60 self.0 = Lines::Many(vec![one, line]);
61 }
62 Lines::Many(mut lines) => {
63 lines.push(line);
64 self.0 = Lines::Many(lines);
65 }
66 }
67 }
68}
69
70#[derive(Clone)]
71enum Lines {
72 Empty,
73 One(Bytes),
74 Many(Vec<Bytes>),
75}
76
77fn eq_many<A: AsRef<[u8]>, B: AsRef<[u8]>>(a: &[A], b: &[B]) -> bool {
78 if a.len() != b.len() {
79 false
80 } else {
81 for (a, b) in a.iter().zip(b.iter()) {
82 if a.as_ref() != b.as_ref() {
83 return false
84 }
85 }
86 true
87 }
88}
89
90fn 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
98impl 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
108impl Eq for Raw {}
109
110impl PartialEq<[Vec<u8>]> for Raw {
111 fn eq(&self, bytes: &[Vec<u8>]) -> bool {
112 eq(self, bytes)
113 }
114}
115
116impl<'a> PartialEq<[&'a [u8]]> for Raw {
117 fn eq(&self, bytes: &[&[u8]]) -> bool {
118 eq(self, bytes)
119 }
120}
121
122impl PartialEq<[String]> for Raw {
123 fn eq(&self, bytes: &[String]) -> bool {
124 eq(self, bytes)
125 }
126}
127
128impl<'a> PartialEq<[&'a str]> for Raw {
129 fn eq(&self, bytes: &[&'a str]) -> bool {
130 eq(self, bytes)
131 }
132}
133
134impl PartialEq<[u8]> for Raw {
135 fn eq(&self, bytes: &[u8]) -> bool {
136 match self.0 {
137 Lines::Empty => bytes.is_empty(),
138 Lines::One(ref line) => line.as_ref() == bytes,
139 Lines::Many(..) => false
140 }
141 }
142}
143
144impl PartialEq<str> for Raw {
145 fn eq(&self, s: &str) -> bool {
146 self == s.as_bytes()
147 }
148}
149
150impl From<Vec<Vec<u8>>> for Raw {
151 #[inline]
152 fn from(val: Vec<Vec<u8>>) -> Raw {
153 Raw(Lines::Many(
154 val.into_iter()
155 .map(|vec| maybe_literal(vec.into()))
156 .collect()
157 ))
158 }
159}
160
161impl From<String> for Raw {
162 #[inline]
163 fn from(val: String) -> Raw {
164 Raw::from(val.into_bytes())
165 }
166}
167
168impl From<Vec<u8>> for Raw {
169 #[inline]
170 fn from(val: Vec<u8>) -> Raw {
171 Raw(Lines::One(maybe_literal(val.into())))
172 }
173}
174
175impl<'a> From<&'a str> for Raw {
176 fn from(val: &'a str) -> Raw {
177 Raw::from(val.as_bytes())
178 }
179}
180
181impl<'a> From<&'a [u8]> for Raw {
182 fn from(val: &'a [u8]) -> Raw {
183 Raw(Lines::One(maybe_literal(val.into())))
184 }
185}
186
187impl From<Bytes> for Raw {
188 #[inline]
189 fn from(val: Bytes) -> Raw {
190 Raw(Lines::One(val))
191 }
192}
193
194pub fn parsed(val: Bytes) -> Raw {
195 Raw(Lines::One(From::from(val)))
196}
197
198pub fn push(raw: &mut Raw, val: Bytes) {
199 raw.push_line(val);
200}
201
202pub fn new() -> Raw {
203 Raw(Lines::Empty)
204}
205
206impl fmt::Debug for Lines {
207 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
208 match *self {
209 Lines::Empty => f.pad("[]"),
210 Lines::One(ref line) => fmt::Debug::fmt(&[line], f),
211 Lines::Many(ref lines) => fmt::Debug::fmt(lines, f)
212 }
213 }
214}
215
216impl ::std::ops::Index<usize> for Raw {
217 type Output = [u8];
218
219 fn index(&self, idx: usize) -> &[u8] {
220 match self.0 {
221 Lines::Empty => panic!("index of out of bounds: {}", idx),
222 Lines::One(ref line) => if idx == 0 {
223 line.as_ref()
224 } else {
225 panic!("index out of bounds: {}", idx)
226 },
227 Lines::Many(ref lines) => lines[idx].as_ref()
228 }
229 }
230}
231
232macro_rules! literals {
233 ($($len:expr => $($value:expr),+;)+) => (
234 fn maybe_literal(s: Cow<[u8]>) -> Bytes {
235 match s.len() {
236 $($len => {
237 $(
238 if s.as_ref() == $value {
239 return Bytes::from_static($value);
240 }
241 )+
242 })+
243
244 _ => ()
245 }
246
247 Bytes::from(s.into_owned())
248 }
249
250 #[test]
251 fn test_literal_lens() {
252 $(
253 $({
254 let s = $value;
255 assert!(s.len() == $len, "{:?} has len of {}, listed as {}", s, s.len(), $len);
256 })+
257 )+
258 }
259 );
260}
261
262literals! {
263 1 => b"*", b"0";
264 3 => b"*/*";
265 4 => b"gzip";
266 5 => b"close";
267 7 => b"chunked";
268 10 => b"keep-alive";
269}
270
271impl<'a> IntoIterator for &'a Raw {
272 type IntoIter = RawLines<'a>;
273 type Item = &'a [u8];
274
275 fn into_iter(self) -> RawLines<'a> {
276 self.iter()
277 }
278}
279
280pub struct RawLines<'a> {
281 inner: &'a Lines,
282 pos: usize,
283}
284
285impl<'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
293impl<'a> Iterator for RawLines<'a> {
294 type Item = &'a [u8];
295
296 #[inline]
297 fn next(&mut self) -> Option<&'a [u8]> {
298 let current_pos = self.pos;
299 self.pos += 1;
300 match *self.inner {
301 Lines::Empty => None,
302 Lines::One(ref line) => {
303 if current_pos == 0 {
304 Some(line.as_ref())
305 } else {
306 None
307 }
308 }
309 Lines::Many(ref lines) => lines.get(current_pos).map(|l| l.as_ref()),
310 }
311 }
312}