rama_http_headers/common/
access_control_allow_methods.rs

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