requiem_http/header/common/
mod.rs1#![cfg_attr(rustfmt, rustfmt_skip)]
9
10pub use self::accept_charset::AcceptCharset;
11pub use self::accept_language::AcceptLanguage;
13pub use self::accept::Accept;
14pub use self::allow::Allow;
15pub use self::cache_control::{CacheControl, CacheDirective};
16pub use self::content_disposition::{ContentDisposition, DispositionType, DispositionParam};
17pub use self::content_language::ContentLanguage;
18pub use self::content_range::{ContentRange, ContentRangeSpec};
19pub use self::content_type::ContentType;
20pub use self::date::Date;
21pub use self::etag::ETag;
22pub use self::expires::Expires;
23pub use self::if_match::IfMatch;
24pub use self::if_modified_since::IfModifiedSince;
25pub use self::if_none_match::IfNoneMatch;
26pub use self::if_range::IfRange;
27pub use self::if_unmodified_since::IfUnmodifiedSince;
28pub use self::last_modified::LastModified;
29#[doc(hidden)]
32#[macro_export]
33macro_rules! __hyper__deref {
34 ($from:ty => $to:ty) => {
35 impl ::std::ops::Deref for $from {
36 type Target = $to;
37
38 #[inline]
39 fn deref(&self) -> &$to {
40 &self.0
41 }
42 }
43
44 impl ::std::ops::DerefMut for $from {
45 #[inline]
46 fn deref_mut(&mut self) -> &mut $to {
47 &mut self.0
48 }
49 }
50 }
51}
52
53#[doc(hidden)]
54#[macro_export]
55macro_rules! __hyper__tm {
56 ($id:ident, $tm:ident{$($tf:item)*}) => {
57 #[allow(unused_imports)]
58 #[cfg(test)]
59 mod $tm{
60 use std::str;
61 use http::Method;
62 use mime::*;
63 use $crate::header::*;
64 use super::$id as HeaderField;
65 $($tf)*
66 }
67
68 }
69}
70
71#[doc(hidden)]
72#[macro_export]
73macro_rules! test_header {
74 ($id:ident, $raw:expr) => {
75 #[test]
76 fn $id() {
77 use $crate::test;
78 use super::*;
79
80 let raw = $raw;
81 let a: Vec<Vec<u8>> = raw.iter().map(|x| x.to_vec()).collect();
82 let mut req = test::TestRequest::default();
83 for item in a {
84 req = req.header(HeaderField::name(), item).take();
85 }
86 let req = req.finish();
87 let value = HeaderField::parse(&req);
88 let result = format!("{}", value.unwrap());
89 let expected = String::from_utf8(raw[0].to_vec()).unwrap();
90 let result_cmp: Vec<String> = result
91 .to_ascii_lowercase()
92 .split(' ')
93 .map(|x| x.to_owned())
94 .collect();
95 let expected_cmp: Vec<String> = expected
96 .to_ascii_lowercase()
97 .split(' ')
98 .map(|x| x.to_owned())
99 .collect();
100 assert_eq!(result_cmp.concat(), expected_cmp.concat());
101 }
102 };
103 ($id:ident, $raw:expr, $typed:expr) => {
104 #[test]
105 fn $id() {
106 use $crate::test;
107
108 let a: Vec<Vec<u8>> = $raw.iter().map(|x| x.to_vec()).collect();
109 let mut req = test::TestRequest::default();
110 for item in a {
111 req.header(HeaderField::name(), item);
112 }
113 let req = req.finish();
114 let val = HeaderField::parse(&req);
115 let typed: Option<HeaderField> = $typed;
116 assert_eq!(val.ok(), typed);
118 if typed.is_some() {
120 let raw = &($raw)[..];
121 let mut iter = raw.iter().map(|b|str::from_utf8(&b[..]).unwrap());
122 let mut joined = String::new();
123 joined.push_str(iter.next().unwrap());
124 for s in iter {
125 joined.push_str(", ");
126 joined.push_str(s);
127 }
128 assert_eq!(format!("{}", typed.unwrap()), joined);
129 }
130 }
131 }
132}
133
134#[macro_export]
135macro_rules! header {
136 ($(#[$a:meta])*($id:ident, $name:expr) => ($item:ty)*) => {
143 $(#[$a])*
144 #[derive(Clone, Debug, PartialEq)]
145 pub struct $id(pub Vec<$item>);
146 __hyper__deref!($id => Vec<$item>);
147 impl $crate::http::header::Header for $id {
148 #[inline]
149 fn name() -> $crate::http::header::HeaderName {
150 $name
151 }
152 #[inline]
153 fn parse<T>(msg: &T) -> Result<Self, $crate::error::ParseError>
154 where T: $crate::HttpMessage
155 {
156 $crate::http::header::from_comma_delimited(
157 msg.headers().get_all(Self::name())).map($id)
158 }
159 }
160 impl std::fmt::Display for $id {
161 #[inline]
162 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> ::std::fmt::Result {
163 $crate::http::header::fmt_comma_delimited(f, &self.0[..])
164 }
165 }
166 impl $crate::http::header::IntoHeaderValue for $id {
167 type Error = $crate::http::header::InvalidHeaderValue;
168
169 fn try_into(self) -> Result<$crate::http::header::HeaderValue, Self::Error> {
170 use std::fmt::Write;
171 let mut writer = $crate::http::header::Writer::new();
172 let _ = write!(&mut writer, "{}", self);
173 $crate::http::header::HeaderValue::from_maybe_shared(writer.take())
174 }
175 }
176 };
177 ($(#[$a:meta])*($id:ident, $name:expr) => ($item:ty)+) => {
179 $(#[$a])*
180 #[derive(Clone, Debug, PartialEq)]
181 pub struct $id(pub Vec<$item>);
182 __hyper__deref!($id => Vec<$item>);
183 impl $crate::http::header::Header for $id {
184 #[inline]
185 fn name() -> $crate::http::header::HeaderName {
186 $name
187 }
188 #[inline]
189 fn parse<T>(msg: &T) -> Result<Self, $crate::error::ParseError>
190 where T: $crate::HttpMessage
191 {
192 $crate::http::header::from_comma_delimited(
193 msg.headers().get_all(Self::name())).map($id)
194 }
195 }
196 impl std::fmt::Display for $id {
197 #[inline]
198 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
199 $crate::http::header::fmt_comma_delimited(f, &self.0[..])
200 }
201 }
202 impl $crate::http::header::IntoHeaderValue for $id {
203 type Error = $crate::http::header::InvalidHeaderValue;
204
205 fn try_into(self) -> Result<$crate::http::header::HeaderValue, Self::Error> {
206 use std::fmt::Write;
207 let mut writer = $crate::http::header::Writer::new();
208 let _ = write!(&mut writer, "{}", self);
209 $crate::http::header::HeaderValue::from_maybe_shared(writer.take())
210 }
211 }
212 };
213 ($(#[$a:meta])*($id:ident, $name:expr) => [$value:ty]) => {
215 $(#[$a])*
216 #[derive(Clone, Debug, PartialEq)]
217 pub struct $id(pub $value);
218 __hyper__deref!($id => $value);
219 impl $crate::http::header::Header for $id {
220 #[inline]
221 fn name() -> $crate::http::header::HeaderName {
222 $name
223 }
224 #[inline]
225 fn parse<T>(msg: &T) -> Result<Self, $crate::error::ParseError>
226 where T: $crate::HttpMessage
227 {
228 $crate::http::header::from_one_raw_str(
229 msg.headers().get(Self::name())).map($id)
230 }
231 }
232 impl std::fmt::Display for $id {
233 #[inline]
234 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
235 std::fmt::Display::fmt(&self.0, f)
236 }
237 }
238 impl $crate::http::header::IntoHeaderValue for $id {
239 type Error = $crate::http::header::InvalidHeaderValue;
240
241 fn try_into(self) -> Result<$crate::http::header::HeaderValue, Self::Error> {
242 self.0.try_into()
243 }
244 }
245 };
246 ($(#[$a:meta])*($id:ident, $name:expr) => {Any / ($item:ty)+}) => {
248 $(#[$a])*
249 #[derive(Clone, Debug, PartialEq)]
250 pub enum $id {
251 Any,
253 Items(Vec<$item>),
255 }
256 impl $crate::http::header::Header for $id {
257 #[inline]
258 fn name() -> $crate::http::header::HeaderName {
259 $name
260 }
261 #[inline]
262 fn parse<T>(msg: &T) -> Result<Self, $crate::error::ParseError>
263 where T: $crate::HttpMessage
264 {
265 let any = msg.headers().get(Self::name()).and_then(|hdr| {
266 hdr.to_str().ok().and_then(|hdr| Some(hdr.trim() == "*"))});
267
268 if let Some(true) = any {
269 Ok($id::Any)
270 } else {
271 Ok($id::Items(
272 $crate::http::header::from_comma_delimited(
273 msg.headers().get_all(Self::name()))?))
274 }
275 }
276 }
277 impl std::fmt::Display for $id {
278 #[inline]
279 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
280 match *self {
281 $id::Any => f.write_str("*"),
282 $id::Items(ref fields) => $crate::http::header::fmt_comma_delimited(
283 f, &fields[..])
284 }
285 }
286 }
287 impl $crate::http::header::IntoHeaderValue for $id {
288 type Error = $crate::http::header::InvalidHeaderValue;
289
290 fn try_into(self) -> Result<$crate::http::header::HeaderValue, Self::Error> {
291 use std::fmt::Write;
292 let mut writer = $crate::http::header::Writer::new();
293 let _ = write!(&mut writer, "{}", self);
294 $crate::http::header::HeaderValue::from_maybe_shared(writer.take())
295 }
296 }
297 };
298
299 ($(#[$a:meta])*($id:ident, $name:expr) => ($item:ty)* $tm:ident{$($tf:item)*}) => {
301 header! {
302 $(#[$a])*
303 ($id, $name) => ($item)*
304 }
305
306 __hyper__tm! { $id, $tm { $($tf)* }}
307 };
308 ($(#[$a:meta])*($id:ident, $n:expr) => ($item:ty)+ $tm:ident{$($tf:item)*}) => {
309 header! {
310 $(#[$a])*
311 ($id, $n) => ($item)+
312 }
313
314 __hyper__tm! { $id, $tm { $($tf)* }}
315 };
316 ($(#[$a:meta])*($id:ident, $name:expr) => [$item:ty] $tm:ident{$($tf:item)*}) => {
317 header! {
318 $(#[$a])* ($id, $name) => [$item]
319 }
320
321 __hyper__tm! { $id, $tm { $($tf)* }}
322 };
323 ($(#[$a:meta])*($id:ident, $name:expr) => {Any / ($item:ty)+} $tm:ident{$($tf:item)*}) => {
324 header! {
325 $(#[$a])*
326 ($id, $name) => {Any / ($item)+}
327 }
328
329 __hyper__tm! { $id, $tm { $($tf)* }}
330 };
331}
332
333
334mod accept_charset;
335mod accept_language;
337mod accept;
338mod allow;
339mod cache_control;
340mod content_disposition;
341mod content_language;
342mod content_range;
343mod content_type;
344mod date;
345mod etag;
346mod expires;
347mod if_match;
348mod if_modified_since;
349mod if_none_match;
350mod if_range;
351mod if_unmodified_since;
352mod last_modified;