rama_http_headers/common/
access_control_expose_headers.rs

1use std::iter::FromIterator;
2
3use rama_http_types::{HeaderName, HeaderValue};
4
5use crate::util::FlatCsv;
6
7/// `Access-Control-Expose-Headers` header, part of
8/// [CORS](http://www.w3.org/TR/cors/#access-control-expose-headers-response-header)
9///
10/// The Access-Control-Expose-Headers header indicates which headers are safe to expose to the
11/// API of a CORS API specification.
12///
13/// # ABNF
14///
15/// ```text
16/// Access-Control-Expose-Headers = "Access-Control-Expose-Headers" ":" #field-name
17/// ```
18///
19/// # Example values
20/// * `ETag, Content-Length`
21///
22/// # Examples
23///
24/// ```
25/// # fn main() {
26/// use rama_http_types::header::{CONTENT_LENGTH, ETAG};
27/// use rama_http_headers::AccessControlExposeHeaders;
28///
29/// let expose = vec![CONTENT_LENGTH, ETAG]
30///     .into_iter()
31///     .collect::<AccessControlExposeHeaders>();
32/// # }
33/// ```
34#[derive(Clone, Debug)]
35pub struct AccessControlExposeHeaders(FlatCsv);
36
37derive_header! {
38    AccessControlExposeHeaders(_),
39    name: ACCESS_CONTROL_EXPOSE_HEADERS
40}
41
42impl AccessControlExposeHeaders {
43    /// Returns an iterator over `HeaderName`s contained within.
44    pub fn iter(&self) -> impl Iterator<Item = HeaderName> + '_ {
45        self.0.iter().filter_map(|s| s.parse().ok())
46    }
47}
48
49impl FromIterator<HeaderName> for AccessControlExposeHeaders {
50    fn from_iter<I>(iter: I) -> Self
51    where
52        I: IntoIterator<Item = HeaderName>,
53    {
54        let flat = iter.into_iter().map(HeaderValue::from).collect();
55        AccessControlExposeHeaders(flat)
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use super::super::{test_decode, test_encode};
62    use super::*;
63
64    #[test]
65    fn iter() {
66        let expose_headers = test_decode::<AccessControlExposeHeaders>(&["foo, bar"]).unwrap();
67
68        let as_vec = expose_headers.iter().collect::<Vec<_>>();
69        assert_eq!(as_vec.len(), 2);
70        assert_eq!(as_vec[0], "foo");
71        assert_eq!(as_vec[1], "bar");
72    }
73
74    #[test]
75    fn from_iter() {
76        let expose: AccessControlExposeHeaders = vec![
77            ::rama_http_types::header::CACHE_CONTROL,
78            ::rama_http_types::header::IF_RANGE,
79        ]
80        .into_iter()
81        .collect();
82
83        let headers = test_encode(expose);
84        assert_eq!(
85            headers["access-control-expose-headers"],
86            "cache-control, if-range"
87        );
88    }
89}