Skip to content

Commit 262c450

Browse files
committedApr 2, 2015
refactor(headers): Introduce header!() macro, improve documentation
The new macro handles single value headers, list headers, and list headers with at least one item. It creates the item for the header and contains its documentation. The new macro allows handling more header cases in the future, it will also be possible to include tests inside the macro. BREAKING CHANGE: Removed impl_header!() and impl_list_header!() macros, use new header!() macro.
1 parent eeba13b commit 262c450

19 files changed

+367
-225
lines changed
 

‎src/header/common/accept.rs

+27-27
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,39 @@ use mime::Mime;
22

33
use header::QualityItem;
44

5-
/// The `Accept` header.
6-
///
7-
/// The `Accept` header is used to tell a server which content-types the client
8-
/// is capable of using. It can be a comma-separated list of `Mime`s, and the
9-
/// priority can be indicated with a `q` parameter.
10-
///
11-
/// Example:
12-
///
13-
/// ```
14-
/// # use hyper::header::Headers;
15-
/// # use hyper::header::Accept;
16-
/// # use hyper::header::qitem;
17-
/// use hyper::mime::Mime;
18-
/// use hyper::mime::TopLevel::Text;
19-
/// use hyper::mime::SubLevel::{Html, Xml};
20-
/// # let mut headers = Headers::new();
21-
/// headers.set(Accept(vec![
22-
/// qitem(Mime(Text, Html, vec![])),
23-
/// qitem(Mime(Text, Xml, vec![])) ]));
24-
/// ```
25-
#[derive(Clone, PartialEq, Debug)]
26-
pub struct Accept(pub Vec<QualityItem<Mime>>);
27-
28-
impl_list_header!(Accept,
29-
"Accept",
30-
Vec<QualityItem<Mime>>);
5+
header! {
6+
#[doc="`Accept` header, defined in [RFC7231](http://tools.ietf.org/html/rfc7231#section-5.3.2)"]
7+
#[doc=""]
8+
#[doc="The `Accept` header field can be used by user agents to specify"]
9+
#[doc="response media types that are acceptable. Accept header fields can"]
10+
#[doc="be used to indicate that the request is specifically limited to a"]
11+
#[doc="small set of desired types, as in the case of a request for an"]
12+
#[doc="in-line image"]
13+
#[doc=""]
14+
#[doc="# ABNF"]
15+
#[doc="```plain"]
16+
#[doc="Accept = #( media-range [ accept-params ] )"]
17+
#[doc=""]
18+
#[doc="media-range = ( \"*/*\""]
19+
#[doc=" / ( type \"/\" \"*\" )"]
20+
#[doc=" / ( type \"/\" subtype )"]
21+
#[doc=" ) *( OWS \";\" OWS parameter )"]
22+
#[doc="accept-params = weight *( accept-ext )"]
23+
#[doc="accept-ext = OWS \";\" OWS token [ \"=\" ( token / quoted-string ) ]"]
24+
#[doc="```"]
25+
#[doc=""]
26+
#[doc="# Notes"]
27+
#[doc="* Using always Mime types to represent `media-range` differs from the ABNF."]
28+
#[doc="* **FIXME**: `accept-ext` is not supported."]
29+
(Accept, "Accept") => (QualityItem<Mime>)+
30+
}
3131

3232
#[cfg(test)]
3333
mod tests {
3434
use mime::*;
3535

3636
use header::{Header, Quality, QualityItem, qitem};
37-
37+
3838
use super::Accept;
3939

4040
#[test]

‎src/header/common/accept_charset.rs

+17-10
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
use header::{Charset, QualityItem};
22

3-
/// The `Accept-Charset` header
4-
///
5-
/// The `Accept-Charset` header can be used by clients to indicate what
6-
/// response charsets they accept.
7-
#[derive(Clone, PartialEq, Debug)]
8-
pub struct AcceptCharset(pub Vec<QualityItem<Charset>>);
9-
10-
impl_list_header!(AcceptCharset,
11-
"Accept-Charset",
12-
Vec<QualityItem<Charset>>);
3+
header! {
4+
#[doc="`Accept-Charset` header, defined in"]
5+
#[doc="[RFC7231](http://tools.ietf.org/html/rfc7231#section-5.3.3)"]
6+
#[doc=""]
7+
#[doc="The `Accept-Charset` header field can be sent by a user agent to"]
8+
#[doc="indicate what charsets are acceptable in textual response content."]
9+
#[doc="This field allows user agents capable of understanding more"]
10+
#[doc="comprehensive or special-purpose charsets to signal that capability"]
11+
#[doc="to an origin server that is capable of representing information in"]
12+
#[doc="those charsets."]
13+
#[doc=""]
14+
#[doc="# ABNF"]
15+
#[doc="```plain"]
16+
#[doc="Accept-Charset = 1#( ( charset / \"*\" ) [ weight ] )"]
17+
#[doc="```"]
18+
(AcceptCharset, "Accept-Charset") => (QualityItem<Charset>)+
19+
}
1320

1421

1522
#[test]

‎src/header/common/accept_encoding.rs

+17-10
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
use header::{Encoding, QualityItem};
22

3-
/// The `Accept-Encoding` header
4-
///
5-
/// The `Accept-Encoding` header can be used by clients to indicate what
6-
/// response encodings they accept.
7-
#[derive(Clone, PartialEq, Debug)]
8-
pub struct AcceptEncoding(pub Vec<QualityItem<Encoding>>);
9-
10-
impl_list_header!(AcceptEncoding,
11-
"Accept-Encoding",
12-
Vec<QualityItem<Encoding>>);
3+
header! {
4+
#[doc="`Accept-Encoding` header, defined in"]
5+
#[doc="[RFC7231](http://tools.ietf.org/html/rfc7231#section-5.3.4)"]
6+
#[doc=""]
7+
#[doc="The `Accept-Encoding` header field can be used by user agents to"]
8+
#[doc="indicate what response content-codings are"]
9+
#[doc="acceptable in the response. An `identity` token is used as a synonym"]
10+
#[doc="for \"no encoding\" in order to communicate when no encoding is"]
11+
#[doc="preferred."]
12+
#[doc=""]
13+
#[doc="# ABNF"]
14+
#[doc="```plain"]
15+
#[doc="Accept-Encoding = #( codings [ weight ] )"]
16+
#[doc="codings = content-coding / \"identity\" / \"*\""]
17+
#[doc="```"]
18+
(AcceptEncoding, "Accept-Encoding") => (QualityItem<Encoding>)*
19+
}
1320

1421
#[cfg(test)]
1522
mod tests {

‎src/header/common/accept_language.rs

+15-10
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,21 @@ impl fmt::Display for Language {
3535
}
3636
}
3737

38-
/// The `Accept-Language` header
39-
///
40-
/// The `Accept-Language` header can be used by clients to indicate what
41-
/// response languages they accept.
42-
#[derive(Clone, PartialEq, Debug)]
43-
pub struct AcceptLanguage(pub Vec<QualityItem<Language>>);
44-
45-
impl_list_header!(AcceptLanguage,
46-
"Accept-Language",
47-
Vec<QualityItem<Language>>);
38+
header! {
39+
#[doc="`Accept-Language` header, defined in"]
40+
#[doc="[RFC7231](http://tools.ietf.org/html/rfc7231#section-5.3.5)"]
41+
#[doc=""]
42+
#[doc="The `Accept-Language` header field can be used by user agents to"]
43+
#[doc="indicate the set of natural languages that are preferred in the"]
44+
#[doc="response."]
45+
#[doc=""]
46+
#[doc="# ABNF"]
47+
#[doc="```plain"]
48+
#[doc="Accept-Language = 1#( language-range [ weight ] )"]
49+
#[doc="language-range = <language-range, see [RFC4647], Section 2.1>"]
50+
#[doc="```"]
51+
(AcceptLanguage, "Accept-Language") => (QualityItem<Language>)+
52+
}
4853

4954
#[cfg(test)]
5055
mod tests {

‎src/header/common/allow.rs

+14-9
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
use method::Method;
22

3-
/// The `Allow` header.
4-
/// See also https://tools.ietf.org/html/rfc7231#section-7.4.1
5-
6-
#[derive(Clone, PartialEq, Debug)]
7-
pub struct Allow(pub Vec<Method>);
8-
9-
impl_list_header!(Allow,
10-
"Allow",
11-
Vec<Method>);
3+
header! {
4+
#[doc="`Allow` header, defined in [RFC7231](http://tools.ietf.org/html/rfc7231#section-7.4.1)"]
5+
#[doc=""]
6+
#[doc="The `Allow` header field lists the set of methods advertised as"]
7+
#[doc="supported by the target resource. The purpose of this field is"]
8+
#[doc="strictly to inform the recipient of valid request methods associated"]
9+
#[doc="with the resource."]
10+
#[doc=""]
11+
#[doc="# ABNF"]
12+
#[doc="```plain"]
13+
#[doc="Allow = #method"]
14+
#[doc="```"]
15+
(Allow, "Allow") => (Method)*
16+
}
1217

1318
#[cfg(test)]
1419
mod tests {

‎src/header/common/content_encoding.rs

+18-14
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
use header::Encoding;
22

3-
/// The `Content-Encoding` header.
4-
///
5-
/// This header describes the encoding of the message body. It can be
6-
/// comma-separated, including multiple encodings.
7-
///
8-
/// ```notrust
9-
/// Content-Encoding: gzip
10-
/// ```
11-
#[derive(Clone, PartialEq, Debug)]
12-
pub struct ContentEncoding(pub Vec<Encoding>);
13-
14-
impl_list_header!(ContentEncoding,
15-
"Content-Encoding",
16-
Vec<Encoding>);
3+
header! {
4+
#[doc="`Content-Encoding` header, defined in"]
5+
#[doc="[RFC7231](http://tools.ietf.org/html/rfc7231#section-3.1.2.2)"]
6+
#[doc=""]
7+
#[doc="The `Content-Encoding` header field indicates what content codings"]
8+
#[doc="have been applied to the representation, beyond those inherent in the"]
9+
#[doc="media type, and thus what decoding mechanisms have to be applied in"]
10+
#[doc="order to obtain data in the media type referenced by the Content-Type"]
11+
#[doc="header field. Content-Encoding is primarily used to allow a"]
12+
#[doc="representation's data to be compressed without losing the identity of"]
13+
#[doc="its underlying media type."]
14+
#[doc=""]
15+
#[doc="# ABNF"]
16+
#[doc="```plain"]
17+
#[doc="Content-Encoding = 1#content-coding"]
18+
#[doc="```"]
19+
(ContentEncoding, "ContentEncoding") => (Encoding)+
20+
}
1721

1822
bench_header!(single, ContentEncoding, { vec![b"gzip".to_vec()] });
1923
bench_header!(multiple, ContentEncoding, { vec![b"gzip, deflate".to_vec()] });

‎src/header/common/content_length.rs

+19-9
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
1-
/// The `Content-Length` header.
2-
///
3-
/// Simply a wrapper around a `u64`.
4-
#[derive(Copy, Clone, PartialEq, Debug)]
5-
pub struct ContentLength(pub u64);
6-
7-
impl_header!(ContentLength,
8-
"Content-Length",
9-
u64);
1+
header! {
2+
#[doc="`Content-Length` header, defined in"]
3+
#[doc="[RFC7230](http://tools.ietf.org/html/rfc7230#section-3.3.2)"]
4+
#[doc=""]
5+
#[doc="When a message does not have a `Transfer-Encoding` header field, a"]
6+
#[doc="Content-Length header field can provide the anticipated size, as a"]
7+
#[doc="decimal number of octets, for a potential payload body. For messages"]
8+
#[doc="that do include a payload body, the Content-Length field-value"]
9+
#[doc="provides the framing information necessary for determining where the"]
10+
#[doc="body (and message) ends. For messages that do not include a payload"]
11+
#[doc="body, the Content-Length indicates the size of the selected"]
12+
#[doc="representation."]
13+
#[doc=""]
14+
#[doc="# ABNF"]
15+
#[doc="```plain"]
16+
#[doc="Content-Length = 1*DIGIT"]
17+
#[doc="```"]
18+
(ContentLength, "Content-Length") => [u64]
19+
}
1020

1121
bench_header!(bench, ContentLength, { vec![b"42349984".to_vec()] });

‎src/header/common/content_type.rs

+18-10
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
use mime::Mime;
22

3-
/// The `Content-Type` header.
4-
///
5-
/// Used to describe the MIME type of message body. Can be used with both
6-
/// requests and responses.
7-
#[derive(Clone, PartialEq, Debug)]
8-
pub struct ContentType(pub Mime);
9-
10-
impl_header!(ContentType,
11-
"Content-Type",
12-
Mime);
3+
header! {
4+
#[doc="`Content-Type` header, defined in"]
5+
#[doc="[RFC7231](http://tools.ietf.org/html/rfc7231#section-3.1.1.5)"]
6+
#[doc=""]
7+
#[doc="The `Content-Type` header field indicates the media type of the"]
8+
#[doc="associated representation: either the representation enclosed in the"]
9+
#[doc="message payload or the selected representation, as determined by the"]
10+
#[doc="message semantics. The indicated media type defines both the data"]
11+
#[doc="format and how that data is intended to be processed by a recipient,"]
12+
#[doc="within the scope of the received message semantics, after any content"]
13+
#[doc="codings indicated by Content-Encoding are decoded."]
14+
#[doc=""]
15+
#[doc="# ABNF"]
16+
#[doc="```plain"]
17+
#[doc="Content-Type = media-type"]
18+
#[doc="```"]
19+
(ContentType, "Content-Type") => [Mime]
20+
}
1321

1422
bench_header!(bench, ContentType, { vec![b"application/json; charset=utf-8".to_vec()] });

‎src/header/common/date.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
use header::HttpDate;
22

3-
/// The `Date` header field.
4-
#[derive(Copy, PartialEq, Clone, Debug)]
5-
pub struct Date(pub HttpDate);
6-
7-
impl_header!(Date, "Date", HttpDate);
3+
header! {
4+
#[doc="`Date` header, defined in [RFC7231](http://tools.ietf.org/html/rfc7231#section-7.1.1.2)"]
5+
#[doc=""]
6+
#[doc="The `Date` header field represents the date and time at which the"]
7+
#[doc="message was originated."]
8+
#[doc=""]
9+
#[doc="# ABNF"]
10+
#[doc="```plain"]
11+
#[doc="Date = HTTP-date"]
12+
#[doc="```"]
13+
(Date, "Date") => [HttpDate]
14+
}
815

916
bench_header!(imf_fixdate, Date, { vec![b"Sun, 07 Nov 1994 08:48:37 GMT".to_vec()] });
1017
bench_header!(rfc_850, Date, { vec![b"Sunday, 06-Nov-94 08:49:37 GMT".to_vec()] });

‎src/header/common/expires.rs

+16-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
11
use header::HttpDate;
22

3-
/// The `Expires` header field.
4-
#[derive(Copy, PartialEq, Clone, Debug)]
5-
pub struct Expires(pub HttpDate);
6-
impl_header!(Expires, "Expires", HttpDate);
3+
header! {
4+
#[doc="`Expires` header, defined in [RFC7234](http://tools.ietf.org/html/rfc7234#section-5.3)"]
5+
#[doc=""]
6+
#[doc="The `Expires` header field gives the date/time after which the"]
7+
#[doc="response is considered stale."]
8+
#[doc=""]
9+
#[doc="The presence of an Expires field does not imply that the original"]
10+
#[doc="resource will change or cease to exist at, before, or after that"]
11+
#[doc="time."]
12+
#[doc=""]
13+
#[doc="# ABNF"]
14+
#[doc="```plain"]
15+
#[doc="Expires = HTTP-date"]
16+
#[doc="```"]
17+
(Expires, "Expires") => [HttpDate]
18+
}
719

820
bench_header!(imf_fixdate, Expires, { vec![b"Sun, 07 Nov 1994 08:48:37 GMT".to_vec()] });
921
bench_header!(rfc_850, Expires, { vec![b"Sunday, 06-Nov-94 08:49:37 GMT".to_vec()] });

‎src/header/common/if_modified_since.rs

+16-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
11
use header::HttpDate;
22

3-
/// The `If-Modified-Since` header field.
4-
#[derive(Copy, PartialEq, Clone, Debug)]
5-
pub struct IfModifiedSince(pub HttpDate);
6-
impl_header!(IfModifiedSince, "If-Modified-Since", HttpDate);
3+
header! {
4+
#[doc="`If-Modified-Since` header, defined in"]
5+
#[doc="[RFC7232](http://tools.ietf.org/html/rfc7232#section-3.3)"]
6+
#[doc=""]
7+
#[doc="The `If-Modified-Since` header field makes a GET or HEAD request"]
8+
#[doc="method conditional on the selected representation's modification date"]
9+
#[doc="being more recent than the date provided in the field-value."]
10+
#[doc="Transfer of the selected representation's data is avoided if that"]
11+
#[doc="data has not changed."]
12+
#[doc=""]
13+
#[doc="# ABNF"]
14+
#[doc="```plain"]
15+
#[doc="If-Unmodified-Since = HTTP-date"]
16+
#[doc="```"]
17+
(IfModifiedSince, "If-Modified-Since") => [HttpDate]
18+
}
719

820
bench_header!(imf_fixdate, IfModifiedSince, { vec![b"Sun, 07 Nov 1994 08:48:37 GMT".to_vec()] });
921
bench_header!(rfc_850, IfModifiedSince, { vec![b"Sunday, 06-Nov-94 08:49:37 GMT".to_vec()] });

‎src/header/common/if_unmodified_since.rs

+16-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,21 @@
11
use header::HttpDate;
22

3-
/// The `If-Unmodified-Since` header field.
4-
#[derive(Copy, PartialEq, Clone, Debug)]
5-
pub struct IfUnmodifiedSince(pub HttpDate);
6-
7-
impl_header!(IfUnmodifiedSince, "If-Unmodified-Since", HttpDate);
3+
header! {
4+
#[doc="`If-Unmodified-Since` header, defined in"]
5+
#[doc="[RFC7232](http://tools.ietf.org/html/rfc7232#section-3.4)"]
6+
#[doc=""]
7+
#[doc="The `If-Unmodified-Since` header field makes the request method"]
8+
#[doc="conditional on the selected representation's last modification date"]
9+
#[doc="being earlier than or equal to the date provided in the field-value."]
10+
#[doc="This field accomplishes the same purpose as If-Match for cases where"]
11+
#[doc="the user agent does not have an entity-tag for the representation."]
12+
#[doc=""]
13+
#[doc="# ABNF"]
14+
#[doc="```plain"]
15+
#[doc="If-Unmodified-Since = HTTP-date"]
16+
#[doc="```"]
17+
(IfUnmodifiedSince, "If-Unmodified-Since") => [HttpDate]
18+
}
819

920
bench_header!(imf_fixdate, IfUnmodifiedSince, { vec![b"Sun, 07 Nov 1994 08:48:37 GMT".to_vec()] });
1021
bench_header!(rfc_850, IfUnmodifiedSince, { vec![b"Sunday, 06-Nov-94 08:49:37 GMT".to_vec()] });

0 commit comments

Comments
 (0)