headers/common/
access_control_allow_methods.rs

1use std::iter::FromIterator;
2
3use http::{HeaderValue, Method};
4
5use crate::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 http;
27/// use http::Method;
28/// use headers::AccessControlAllowMethods;
29///
30/// let allow_methods = vec![Method::GET, Method::PUT]
31///     .into_iter()
32///     .collect::<AccessControlAllowMethods>();
33/// ```
34#[derive(Clone, Debug, PartialEq)]
35pub struct AccessControlAllowMethods(FlatCsv);
36
37derive_header! {
38    AccessControlAllowMethods(_),
39    name: ACCESS_CONTROL_ALLOW_METHODS
40}
41
42impl AccessControlAllowMethods {
43    /// Returns an iterator over `Method`s contained within.
44    pub fn iter(&self) -> impl Iterator<Item = Method> + '_ {
45        self.0.iter().filter_map(|s| s.parse().ok())
46    }
47}
48
49impl FromIterator<Method> for AccessControlAllowMethods {
50    fn from_iter<I>(iter: I) -> Self
51    where
52        I: IntoIterator<Item = Method>,
53    {
54        let methods = iter
55            .into_iter()
56            .map(|method| {
57                method
58                    .as_str()
59                    .parse::<HeaderValue>()
60                    .expect("Method is a valid HeaderValue")
61            })
62            .collect();
63
64        AccessControlAllowMethods(methods)
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use super::super::{test_decode, test_encode};
71    use super::*;
72
73    #[test]
74    fn iter() {
75        let allowed = test_decode::<AccessControlAllowMethods>(&["GET, PUT"]).unwrap();
76
77        let as_vec = allowed.iter().collect::<Vec<_>>();
78        assert_eq!(as_vec.len(), 2);
79        assert_eq!(as_vec[0], Method::GET);
80        assert_eq!(as_vec[1], Method::PUT);
81    }
82
83    #[test]
84    fn from_iter() {
85        let allow: AccessControlAllowMethods = vec![Method::GET, Method::PUT].into_iter().collect();
86
87        let headers = test_encode(allow);
88        assert_eq!(headers["access-control-allow-methods"], "GET, PUT");
89    }
90}