hyper_sync/header/common/accept_ranges.rs
1use std::fmt::{self, Display};
2use std::str::FromStr;
3
4header! {
5 /// `Accept-Ranges` header, defined in
6 /// [RFC7233](http://tools.ietf.org/html/rfc7233#section-2.3)
7 ///
8 /// The `Accept-Ranges` header field allows a server to indicate that it
9 /// supports range requests for the target resource.
10 ///
11 /// # ABNF
12 ///
13 /// ```text
14 /// Accept-Ranges = acceptable-ranges
15 /// acceptable-ranges = 1#range-unit / \"none\"
16 ///
17 /// # Example values
18 /// * `bytes`
19 /// * `none`
20 /// * `unknown-unit`
21 /// ```
22 ///
23 /// # Examples
24 /// ```
25 /// use hyper_sync::header::{Headers, AcceptRanges, RangeUnit};
26 ///
27 /// let mut headers = Headers::new();
28 /// headers.set(AcceptRanges(vec![RangeUnit::Bytes]));
29 /// ```
30 ///
31 /// ```
32 /// use hyper_sync::header::{Headers, AcceptRanges, RangeUnit};
33 ///
34 /// let mut headers = Headers::new();
35 /// headers.set(AcceptRanges(vec![RangeUnit::None]));
36 /// ```
37 ///
38 /// ```
39 /// use hyper_sync::header::{Headers, AcceptRanges, RangeUnit};
40 ///
41 /// let mut headers = Headers::new();
42 /// headers.set(
43 /// AcceptRanges(vec![
44 /// RangeUnit::Unregistered("nibbles".to_owned()),
45 /// RangeUnit::Bytes,
46 /// RangeUnit::Unregistered("doublets".to_owned()),
47 /// RangeUnit::Unregistered("quadlets".to_owned()),
48 /// ])
49 /// );
50 /// ```
51 (AcceptRanges, "Accept-Ranges") => (RangeUnit)+
52
53 test_acccept_ranges {
54 test_header!(test1, vec![b"bytes"]);
55 test_header!(test2, vec![b"none"]);
56 test_header!(test3, vec![b"unknown-unit"]);
57 test_header!(test4, vec![b"bytes, unknown-unit"]);
58 }
59}
60
61/// Range Units, described in [RFC7233](http://tools.ietf.org/html/rfc7233#section-2)
62///
63/// A representation can be partitioned into subranges according to
64/// various structural units, depending on the structure inherent in the
65/// representation's media type.
66///
67/// # ABNF
68///
69/// ```text
70/// range-unit = bytes-unit / other-range-unit
71/// bytes-unit = "bytes"
72/// other-range-unit = token
73/// ```
74#[derive(Clone, Debug, Eq, PartialEq)]
75pub enum RangeUnit {
76 /// Indicating byte-range requests are supported.
77 Bytes,
78 /// Reserved as keyword, indicating no ranges are supported.
79 None,
80 /// The given range unit is not registered at IANA.
81 Unregistered(String),
82}
83
84
85impl FromStr for RangeUnit {
86 type Err = ::Error;
87 fn from_str(s: &str) -> ::Result<Self> {
88 match s {
89 "bytes" => Ok(RangeUnit::Bytes),
90 "none" => Ok(RangeUnit::None),
91 // FIXME: Check if s is really a Token
92 _ => Ok(RangeUnit::Unregistered(s.to_owned())),
93 }
94 }
95}
96
97impl Display for RangeUnit {
98 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
99 match *self {
100 RangeUnit::Bytes => f.write_str("bytes"),
101 RangeUnit::None => f.write_str("none"),
102 RangeUnit::Unregistered(ref x) => f.write_str(x),
103 }
104 }
105}