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