hyper_sync/header/common/accept.rs
1use mime::{self, Mime};
2
3use header::{QualityItem, qitem};
4
5header! {
6 /// `Accept` header, defined in [RFC7231](http://tools.ietf.org/html/rfc7231#section-5.3.2)
7 ///
8 /// The `Accept` header field can be used by user agents to specify
9 /// response media types that are acceptable. Accept header fields can
10 /// be used to indicate that the request is specifically limited to a
11 /// small set of desired types, as in the case of a request for an
12 /// in-line image
13 ///
14 /// # ABNF
15 ///
16 /// ```text
17 /// Accept = #( media-range [ accept-params ] )
18 ///
19 /// media-range = ( "*/*"
20 /// / ( type "/" "*" )
21 /// / ( type "/" subtype )
22 /// ) *( OWS ";" OWS parameter )
23 /// accept-params = weight *( accept-ext )
24 /// accept-ext = OWS ";" OWS token [ "=" ( token / quoted-string ) ]
25 /// ```
26 ///
27 /// # Example values
28 /// * `audio/*; q=0.2, audio/basic`
29 /// * `text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c`
30 ///
31 /// # Examples
32 /// ```
33 /// use hyper_sync::header::{Headers, Accept, qitem};
34 /// use hyper_sync::mime;
35 ///
36 /// let mut headers = Headers::new();
37 ///
38 /// headers.set(
39 /// Accept(vec![
40 /// qitem(mime::TEXT_HTML),
41 /// ])
42 /// );
43 /// ```
44 ///
45 /// ```
46 /// use hyper_sync::header::{Headers, Accept, qitem};
47 /// use hyper_sync::mime;
48 ///
49 /// let mut headers = Headers::new();
50 /// headers.set(
51 /// Accept(vec![
52 /// qitem(mime::APPLICATION_JSON),
53 /// ])
54 /// );
55 /// ```
56 /// ```
57 /// use hyper_sync::header::{Headers, Accept, QualityItem, q, qitem};
58 /// use hyper_sync::mime;
59 ///
60 /// let mut headers = Headers::new();
61 ///
62 /// headers.set(
63 /// Accept(vec![
64 /// qitem(mime::TEXT_HTML),
65 /// qitem("application/xhtml+xml".parse().unwrap()),
66 /// QualityItem::new(
67 /// mime::TEXT_XML,
68 /// q(900)
69 /// ),
70 /// qitem("image/webp".parse().unwrap()),
71 /// QualityItem::new(
72 /// mime::STAR_STAR,
73 /// q(800)
74 /// ),
75 /// ])
76 /// );
77 /// ```
78 (Accept, "Accept") => (QualityItem<Mime>)+
79
80 test_accept {
81 // Tests from the RFC
82 test_header!(
83 test1,
84 vec![b"audio/*; q=0.2, audio/basic"],
85 Some(HeaderField(vec![
86 QualityItem::new("audio/*".parse().unwrap(), q(200)),
87 qitem("audio/basic".parse().unwrap()),
88 ])));
89 test_header!(
90 test2,
91 vec![b"text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c"],
92 Some(HeaderField(vec![
93 QualityItem::new(TEXT_PLAIN, q(500)),
94 qitem(TEXT_HTML),
95 QualityItem::new(
96 "text/x-dvi".parse().unwrap(),
97 q(800)),
98 qitem("text/x-c".parse().unwrap()),
99 ])));
100 // Custom tests
101 test_header!(
102 test3,
103 vec![b"text/plain; charset=utf-8"],
104 Some(Accept(vec![
105 qitem(TEXT_PLAIN_UTF_8),
106 ])));
107 test_header!(
108 test4,
109 vec![b"text/plain; charset=utf-8; q=0.5"],
110 Some(Accept(vec![
111 QualityItem::new(TEXT_PLAIN_UTF_8,
112 q(500)),
113 ])));
114
115 #[test]
116 fn test_fuzzing1() {
117 let raw: Raw = "chunk#;e".into();
118 let header = Accept::parse_header(&raw);
119 assert!(header.is_ok());
120 }
121 }
122}
123
124impl Accept {
125 /// A constructor to easily create `Accept: */*`.
126 pub fn star() -> Accept {
127 Accept(vec![qitem(mime::STAR_STAR)])
128 }
129
130 /// A constructor to easily create `Accept: application/json`.
131 pub fn json() -> Accept {
132 Accept(vec![qitem(mime::APPLICATION_JSON)])
133 }
134
135 /// A constructor to easily create `Accept: text/*`.
136 pub fn text() -> Accept {
137 Accept(vec![qitem(mime::TEXT_STAR)])
138 }
139
140 /// A constructor to easily create `Accept: image/*`.
141 pub fn image() -> Accept {
142 Accept(vec![qitem(mime::IMAGE_STAR)])
143 }
144}
145
146
147bench_header!(bench, Accept, { vec![b"text/plain; q=0.5, text/html".to_vec()] });