Skip to content

Commit

Permalink
Merge pull request #419 from pyfisch/refactorheaders1
Browse files Browse the repository at this point in the history
refactor(headers): Introduce header!() macro, improve documentation
  • Loading branch information
seanmonstar committed Apr 2, 2015
2 parents 05e505e + 262c450 commit b4aeeb3
Show file tree
Hide file tree
Showing 19 changed files with 367 additions and 225 deletions.
54 changes: 27 additions & 27 deletions src/header/common/accept.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,39 @@ use mime::Mime;

use header::QualityItem;

/// The `Accept` header.
///
/// The `Accept` header is used to tell a server which content-types the client
/// is capable of using. It can be a comma-separated list of `Mime`s, and the
/// priority can be indicated with a `q` parameter.
///
/// Example:
///
/// ```
/// # use hyper::header::Headers;
/// # use hyper::header::Accept;
/// # use hyper::header::qitem;
/// use hyper::mime::Mime;
/// use hyper::mime::TopLevel::Text;
/// use hyper::mime::SubLevel::{Html, Xml};
/// # let mut headers = Headers::new();
/// headers.set(Accept(vec![
/// qitem(Mime(Text, Html, vec![])),
/// qitem(Mime(Text, Xml, vec![])) ]));
/// ```
#[derive(Clone, PartialEq, Debug)]
pub struct Accept(pub Vec<QualityItem<Mime>>);

impl_list_header!(Accept,
"Accept",
Vec<QualityItem<Mime>>);
header! {
#[doc="`Accept` header, defined in [RFC7231](http://tools.ietf.org/html/rfc7231#section-5.3.2)"]
#[doc=""]
#[doc="The `Accept` header field can be used by user agents to specify"]
#[doc="response media types that are acceptable. Accept header fields can"]
#[doc="be used to indicate that the request is specifically limited to a"]
#[doc="small set of desired types, as in the case of a request for an"]
#[doc="in-line image"]
#[doc=""]
#[doc="# ABNF"]
#[doc="```plain"]
#[doc="Accept = #( media-range [ accept-params ] )"]
#[doc=""]
#[doc="media-range = ( \"*/*\""]
#[doc=" / ( type \"/\" \"*\" )"]
#[doc=" / ( type \"/\" subtype )"]
#[doc=" ) *( OWS \";\" OWS parameter )"]
#[doc="accept-params = weight *( accept-ext )"]
#[doc="accept-ext = OWS \";\" OWS token [ \"=\" ( token / quoted-string ) ]"]
#[doc="```"]
#[doc=""]
#[doc="# Notes"]
#[doc="* Using always Mime types to represent `media-range` differs from the ABNF."]
#[doc="* **FIXME**: `accept-ext` is not supported."]
(Accept, "Accept") => (QualityItem<Mime>)+
}

#[cfg(test)]
mod tests {
use mime::*;

use header::{Header, Quality, QualityItem, qitem};

use super::Accept;

#[test]
Expand Down
27 changes: 17 additions & 10 deletions src/header/common/accept_charset.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
use header::{Charset, QualityItem};

/// The `Accept-Charset` header
///
/// The `Accept-Charset` header can be used by clients to indicate what
/// response charsets they accept.
#[derive(Clone, PartialEq, Debug)]
pub struct AcceptCharset(pub Vec<QualityItem<Charset>>);

impl_list_header!(AcceptCharset,
"Accept-Charset",
Vec<QualityItem<Charset>>);
header! {
#[doc="`Accept-Charset` header, defined in"]
#[doc="[RFC7231](http://tools.ietf.org/html/rfc7231#section-5.3.3)"]
#[doc=""]
#[doc="The `Accept-Charset` header field can be sent by a user agent to"]
#[doc="indicate what charsets are acceptable in textual response content."]
#[doc="This field allows user agents capable of understanding more"]
#[doc="comprehensive or special-purpose charsets to signal that capability"]
#[doc="to an origin server that is capable of representing information in"]
#[doc="those charsets."]
#[doc=""]
#[doc="# ABNF"]
#[doc="```plain"]
#[doc="Accept-Charset = 1#( ( charset / \"*\" ) [ weight ] )"]
#[doc="```"]
(AcceptCharset, "Accept-Charset") => (QualityItem<Charset>)+
}


#[test]
Expand Down
27 changes: 17 additions & 10 deletions src/header/common/accept_encoding.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
use header::{Encoding, QualityItem};

/// The `Accept-Encoding` header
///
/// The `Accept-Encoding` header can be used by clients to indicate what
/// response encodings they accept.
#[derive(Clone, PartialEq, Debug)]
pub struct AcceptEncoding(pub Vec<QualityItem<Encoding>>);

impl_list_header!(AcceptEncoding,
"Accept-Encoding",
Vec<QualityItem<Encoding>>);
header! {
#[doc="`Accept-Encoding` header, defined in"]
#[doc="[RFC7231](http://tools.ietf.org/html/rfc7231#section-5.3.4)"]
#[doc=""]
#[doc="The `Accept-Encoding` header field can be used by user agents to"]
#[doc="indicate what response content-codings are"]
#[doc="acceptable in the response. An `identity` token is used as a synonym"]
#[doc="for \"no encoding\" in order to communicate when no encoding is"]
#[doc="preferred."]
#[doc=""]
#[doc="# ABNF"]
#[doc="```plain"]
#[doc="Accept-Encoding = #( codings [ weight ] )"]
#[doc="codings = content-coding / \"identity\" / \"*\""]
#[doc="```"]
(AcceptEncoding, "Accept-Encoding") => (QualityItem<Encoding>)*
}

#[cfg(test)]
mod tests {
Expand Down
25 changes: 15 additions & 10 deletions src/header/common/accept_language.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,21 @@ impl fmt::Display for Language {
}
}

/// The `Accept-Language` header
///
/// The `Accept-Language` header can be used by clients to indicate what
/// response languages they accept.
#[derive(Clone, PartialEq, Debug)]
pub struct AcceptLanguage(pub Vec<QualityItem<Language>>);

impl_list_header!(AcceptLanguage,
"Accept-Language",
Vec<QualityItem<Language>>);
header! {
#[doc="`Accept-Language` header, defined in"]
#[doc="[RFC7231](http://tools.ietf.org/html/rfc7231#section-5.3.5)"]
#[doc=""]
#[doc="The `Accept-Language` header field can be used by user agents to"]
#[doc="indicate the set of natural languages that are preferred in the"]
#[doc="response."]
#[doc=""]
#[doc="# ABNF"]
#[doc="```plain"]
#[doc="Accept-Language = 1#( language-range [ weight ] )"]
#[doc="language-range = <language-range, see [RFC4647], Section 2.1>"]
#[doc="```"]
(AcceptLanguage, "Accept-Language") => (QualityItem<Language>)+
}

#[cfg(test)]
mod tests {
Expand Down
23 changes: 14 additions & 9 deletions src/header/common/allow.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
use method::Method;

/// The `Allow` header.
/// See also https://tools.ietf.org/html/rfc7231#section-7.4.1
#[derive(Clone, PartialEq, Debug)]
pub struct Allow(pub Vec<Method>);

impl_list_header!(Allow,
"Allow",
Vec<Method>);
header! {
#[doc="`Allow` header, defined in [RFC7231](http://tools.ietf.org/html/rfc7231#section-7.4.1)"]
#[doc=""]
#[doc="The `Allow` header field lists the set of methods advertised as"]
#[doc="supported by the target resource. The purpose of this field is"]
#[doc="strictly to inform the recipient of valid request methods associated"]
#[doc="with the resource."]
#[doc=""]
#[doc="# ABNF"]
#[doc="```plain"]
#[doc="Allow = #method"]
#[doc="```"]
(Allow, "Allow") => (Method)*
}

#[cfg(test)]
mod tests {
Expand Down
32 changes: 18 additions & 14 deletions src/header/common/content_encoding.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
use header::Encoding;

/// The `Content-Encoding` header.
///
/// This header describes the encoding of the message body. It can be
/// comma-separated, including multiple encodings.
///
/// ```notrust
/// Content-Encoding: gzip
/// ```
#[derive(Clone, PartialEq, Debug)]
pub struct ContentEncoding(pub Vec<Encoding>);

impl_list_header!(ContentEncoding,
"Content-Encoding",
Vec<Encoding>);
header! {
#[doc="`Content-Encoding` header, defined in"]
#[doc="[RFC7231](http://tools.ietf.org/html/rfc7231#section-3.1.2.2)"]
#[doc=""]
#[doc="The `Content-Encoding` header field indicates what content codings"]
#[doc="have been applied to the representation, beyond those inherent in the"]
#[doc="media type, and thus what decoding mechanisms have to be applied in"]
#[doc="order to obtain data in the media type referenced by the Content-Type"]
#[doc="header field. Content-Encoding is primarily used to allow a"]
#[doc="representation's data to be compressed without losing the identity of"]
#[doc="its underlying media type."]
#[doc=""]
#[doc="# ABNF"]
#[doc="```plain"]
#[doc="Content-Encoding = 1#content-coding"]
#[doc="```"]
(ContentEncoding, "ContentEncoding") => (Encoding)+
}

bench_header!(single, ContentEncoding, { vec![b"gzip".to_vec()] });
bench_header!(multiple, ContentEncoding, { vec![b"gzip, deflate".to_vec()] });
28 changes: 19 additions & 9 deletions src/header/common/content_length.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
/// The `Content-Length` header.
///
/// Simply a wrapper around a `u64`.
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct ContentLength(pub u64);

impl_header!(ContentLength,
"Content-Length",
u64);
header! {
#[doc="`Content-Length` header, defined in"]
#[doc="[RFC7230](http://tools.ietf.org/html/rfc7230#section-3.3.2)"]
#[doc=""]
#[doc="When a message does not have a `Transfer-Encoding` header field, a"]
#[doc="Content-Length header field can provide the anticipated size, as a"]
#[doc="decimal number of octets, for a potential payload body. For messages"]
#[doc="that do include a payload body, the Content-Length field-value"]
#[doc="provides the framing information necessary for determining where the"]
#[doc="body (and message) ends. For messages that do not include a payload"]
#[doc="body, the Content-Length indicates the size of the selected"]
#[doc="representation."]
#[doc=""]
#[doc="# ABNF"]
#[doc="```plain"]
#[doc="Content-Length = 1*DIGIT"]
#[doc="```"]
(ContentLength, "Content-Length") => [u64]
}

bench_header!(bench, ContentLength, { vec![b"42349984".to_vec()] });
28 changes: 18 additions & 10 deletions src/header/common/content_type.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
use mime::Mime;

/// The `Content-Type` header.
///
/// Used to describe the MIME type of message body. Can be used with both
/// requests and responses.
#[derive(Clone, PartialEq, Debug)]
pub struct ContentType(pub Mime);

impl_header!(ContentType,
"Content-Type",
Mime);
header! {
#[doc="`Content-Type` header, defined in"]
#[doc="[RFC7231](http://tools.ietf.org/html/rfc7231#section-3.1.1.5)"]
#[doc=""]
#[doc="The `Content-Type` header field indicates the media type of the"]
#[doc="associated representation: either the representation enclosed in the"]
#[doc="message payload or the selected representation, as determined by the"]
#[doc="message semantics. The indicated media type defines both the data"]
#[doc="format and how that data is intended to be processed by a recipient,"]
#[doc="within the scope of the received message semantics, after any content"]
#[doc="codings indicated by Content-Encoding are decoded."]
#[doc=""]
#[doc="# ABNF"]
#[doc="```plain"]
#[doc="Content-Type = media-type"]
#[doc="```"]
(ContentType, "Content-Type") => [Mime]
}

bench_header!(bench, ContentType, { vec![b"application/json; charset=utf-8".to_vec()] });
17 changes: 12 additions & 5 deletions src/header/common/date.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
use header::HttpDate;

/// The `Date` header field.
#[derive(Copy, PartialEq, Clone, Debug)]
pub struct Date(pub HttpDate);

impl_header!(Date, "Date", HttpDate);
header! {
#[doc="`Date` header, defined in [RFC7231](http://tools.ietf.org/html/rfc7231#section-7.1.1.2)"]
#[doc=""]
#[doc="The `Date` header field represents the date and time at which the"]
#[doc="message was originated."]
#[doc=""]
#[doc="# ABNF"]
#[doc="```plain"]
#[doc="Date = HTTP-date"]
#[doc="```"]
(Date, "Date") => [HttpDate]
}

bench_header!(imf_fixdate, Date, { vec![b"Sun, 07 Nov 1994 08:48:37 GMT".to_vec()] });
bench_header!(rfc_850, Date, { vec![b"Sunday, 06-Nov-94 08:49:37 GMT".to_vec()] });
Expand Down
20 changes: 16 additions & 4 deletions src/header/common/expires.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
use header::HttpDate;

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

bench_header!(imf_fixdate, Expires, { vec![b"Sun, 07 Nov 1994 08:48:37 GMT".to_vec()] });
bench_header!(rfc_850, Expires, { vec![b"Sunday, 06-Nov-94 08:49:37 GMT".to_vec()] });
Expand Down
20 changes: 16 additions & 4 deletions src/header/common/if_modified_since.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
use header::HttpDate;

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

bench_header!(imf_fixdate, IfModifiedSince, { vec![b"Sun, 07 Nov 1994 08:48:37 GMT".to_vec()] });
bench_header!(rfc_850, IfModifiedSince, { vec![b"Sunday, 06-Nov-94 08:49:37 GMT".to_vec()] });
Expand Down
21 changes: 16 additions & 5 deletions src/header/common/if_unmodified_since.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
use header::HttpDate;

/// The `If-Unmodified-Since` header field.
#[derive(Copy, PartialEq, Clone, Debug)]
pub struct IfUnmodifiedSince(pub HttpDate);

impl_header!(IfUnmodifiedSince, "If-Unmodified-Since", HttpDate);
header! {
#[doc="`If-Unmodified-Since` header, defined in"]
#[doc="[RFC7232](http://tools.ietf.org/html/rfc7232#section-3.4)"]
#[doc=""]
#[doc="The `If-Unmodified-Since` header field makes the request method"]
#[doc="conditional on the selected representation's last modification date"]
#[doc="being earlier than or equal to the date provided in the field-value."]
#[doc="This field accomplishes the same purpose as If-Match for cases where"]
#[doc="the user agent does not have an entity-tag for the representation."]
#[doc=""]
#[doc="# ABNF"]
#[doc="```plain"]
#[doc="If-Unmodified-Since = HTTP-date"]
#[doc="```"]
(IfUnmodifiedSince, "If-Unmodified-Since") => [HttpDate]
}

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

0 comments on commit b4aeeb3

Please sign in to comment.