headers_ext/common/
access_control_allow_methods.rs

1use std::iter::FromIterator;
2
3use http::Method;
4
5use util::FlatCsv;
6
7/// `Access-Control-Allow-Methods` header, part of
8/// [CORS](http://www.w3.org/TR/cors/#access-control-allow-methods-response-header)
9///
10/// The `Access-Control-Allow-Methods` header indicates, as part of the
11/// response to a preflight request, which methods can be used during the
12/// actual request.
13///
14/// # ABNF
15///
16/// ```text
17/// Access-Control-Allow-Methods: "Access-Control-Allow-Methods" ":" #Method
18/// ```
19///
20/// # Example values
21/// * `PUT, DELETE, XMODIFY`
22///
23/// # Examples
24///
25/// ```
26/// # extern crate headers_ext as headers;
27/// extern crate http;
28/// use http::Method;
29/// use headers::AccessControlAllowMethods;
30///
31/// let allow_methods = vec![Method::GET, Method::PUT]
32///     .into_iter()
33///     .collect::<AccessControlAllowMethods>();
34/// ```
35#[derive(Clone, Debug, PartialEq, Header)]
36pub struct AccessControlAllowMethods(FlatCsv);
37
38impl AccessControlAllowMethods {
39    /// Returns an iterator over `Method`s contained within.
40    pub fn iter<'a>(&'a self) -> impl Iterator<Item = Method> + 'a {
41        self
42            .0
43            .iter()
44            .filter_map(|s| {
45                s.parse().ok()
46            })
47    }
48}
49
50impl FromIterator<Method> for AccessControlAllowMethods {
51    fn from_iter<I>(iter: I) -> Self
52    where
53        I: IntoIterator<Item=Method>,
54    {
55        let methods = iter
56            .into_iter()
57            .map(|method| {
58                method
59                    .as_str()
60                    .parse::<::HeaderValue>()
61                    .expect("Method is a valid HeaderValue")
62            })
63            .collect();
64
65        AccessControlAllowMethods(methods)
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72    use super::super::{test_decode, test_encode};
73
74    #[test]
75    fn iter() {
76        let allowed = test_decode::<AccessControlAllowMethods>(
77            &["GET, PUT"]
78        ).unwrap();
79
80        let as_vec = allowed.iter().collect::<Vec<_>>();
81        assert_eq!(as_vec.len(), 2);
82        assert_eq!(as_vec[0], Method::GET);
83        assert_eq!(as_vec[1], Method::PUT);
84    }
85
86    #[test]
87    fn from_iter() {
88        let allow: AccessControlAllowMethods = vec![
89            Method::GET,
90            Method::PUT,
91        ].into_iter().collect();
92
93        let headers = test_encode(allow);
94        assert_eq!(headers["access-control-allow-methods"], "GET, PUT");
95    }
96}
97