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