1 use std::iter::FromIterator;
2 
3 use {HeaderName, HeaderValue};
4 use util::FlatCsv;
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, Header)]
36 pub struct AccessControlExposeHeaders(FlatCsv);
37 
38 impl AccessControlExposeHeaders {
39     /// Returns an iterator over `HeaderName`s contained within.
iter<'a>(&'a self) -> impl Iterator<Item = HeaderName> + 'a40     pub fn iter<'a>(&'a self) -> impl Iterator<Item = HeaderName> + 'a {
41         self
42             .0
43             .iter()
44             .filter_map(|s| {
45                 s.parse().ok()
46             })
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
56             .into_iter()
57             .map(HeaderValue::from)
58             .collect();
59         AccessControlExposeHeaders(flat)
60     }
61 }
62 
63 #[cfg(test)]
64 mod tests {
65     use super::*;
66     use super::super::{test_decode, test_encode};
67 
68     #[test]
iter()69     fn iter() {
70         let expose_headers = test_decode::<AccessControlExposeHeaders>(
71             &["foo, bar"]
72         ).unwrap();
73 
74         let as_vec = expose_headers.iter().collect::<Vec<_>>();
75         assert_eq!(as_vec.len(), 2);
76         assert_eq!(as_vec[0], "foo");
77         assert_eq!(as_vec[1], "bar");
78     }
79 
80     #[test]
from_iter()81     fn from_iter() {
82         let expose: AccessControlExposeHeaders = vec![
83             ::http::header::CACHE_CONTROL,
84             ::http::header::IF_RANGE,
85         ].into_iter().collect();
86 
87         let headers = test_encode(expose);
88         assert_eq!(headers["access-control-expose-headers"], "cache-control, if-range");
89     }
90 }
91 
92