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