11//! Apply the HTTP method if the ETag matches.
22
3- use crate :: conditional:: VaryDirective ;
43use crate :: headers:: { HeaderName , HeaderValue , Headers , ToHeaderValues , VARY } ;
54
6- use std:: convert:: TryInto ;
75use std:: fmt:: { self , Debug , Write } ;
86use std:: iter:: Iterator ;
97use std:: option;
@@ -39,13 +37,14 @@ use std::str::FromStr;
3937/// # Ok(()) }
4038/// ```
4139pub struct Vary {
42- entries : Vec < VaryDirective > ,
40+ entries : Vec < HeaderName > ,
41+ wildcard : bool ,
4342}
4443
4544impl Vary {
4645 /// Create a new instance of `Vary`.
4746 pub fn new ( ) -> Self {
48- Self { entries : vec ! [ ] }
47+ Self { entries : vec ! [ ] , wildcard : false }
4948 }
5049
5150 /// Create a new instance from headers.
@@ -56,14 +55,20 @@ impl Vary {
5655 None => return Ok ( None ) ,
5756 } ;
5857
58+ let mut wildcard = false ;
5959 for value in headers {
6060 for part in value. as_str ( ) . trim ( ) . split ( ',' ) {
61- let entry = VaryDirective :: from_str ( part) ?;
61+ let part = part. trim ( ) ;
62+ if part == "*" {
63+ wildcard = true ;
64+ continue ;
65+ }
66+ let entry = HeaderName :: from_str ( part. trim ( ) ) ?;
6267 entries. push ( entry) ;
6368 }
6469 }
6570
66- Ok ( Some ( Self { entries } ) )
71+ Ok ( Some ( Self { entries, wildcard } ) )
6772 }
6873
6974 /// Sets the `If-Match` header.
@@ -76,11 +81,21 @@ impl Vary {
7681 VARY
7782 }
7883
84+ /// Returns `true` if a wildcard directive was set.
85+ pub fn wildcard ( & self ) -> bool {
86+ self . wildcard
87+ }
88+
89+ /// Set the wildcard directive.
90+ pub fn set_wildcard ( & mut self , wildcard : bool ) {
91+ self . wildcard = wildcard
92+ }
93+
7994 /// Get the `HeaderValue`.
8095 pub fn value ( & self ) -> HeaderValue {
8196 let mut output = String :: new ( ) ;
82- for ( n, directive ) in self . entries . iter ( ) . enumerate ( ) {
83- let directive: HeaderValue = directive . clone ( ) . into ( ) ;
97+ for ( n, name ) in self . entries . iter ( ) . enumerate ( ) {
98+ let directive: HeaderValue = name . as_str ( ) . parse ( ) . expect ( "Could not convert a HeaderName into a HeaderValue" ) ;
8499 match n {
85100 0 => write ! ( output, "{}" , directive) . unwrap ( ) ,
86101 _ => write ! ( output, ", {}" , directive) . unwrap ( ) ,
@@ -94,9 +109,9 @@ impl Vary {
94109 /// Push a directive into the list of entries.
95110 pub fn push (
96111 & mut self ,
97- directive : impl TryInto < VaryDirective , Error = crate :: Error > ,
112+ directive : impl Into < HeaderName > ,
98113 ) -> crate :: Result < ( ) > {
99- self . entries . push ( directive. try_into ( ) ? ) ;
114+ self . entries . push ( directive. into ( ) ) ;
100115 Ok ( ( ) )
101116 }
102117
@@ -116,7 +131,7 @@ impl Vary {
116131}
117132
118133impl IntoIterator for Vary {
119- type Item = VaryDirective ;
134+ type Item = HeaderName ;
120135 type IntoIter = IntoIter ;
121136
122137 #[ inline]
@@ -128,7 +143,7 @@ impl IntoIterator for Vary {
128143}
129144
130145impl < ' a > IntoIterator for & ' a Vary {
131- type Item = & ' a VaryDirective ;
146+ type Item = & ' a HeaderName ;
132147 type IntoIter = Iter < ' a > ;
133148
134149 #[ inline]
@@ -138,7 +153,7 @@ impl<'a> IntoIterator for &'a Vary {
138153}
139154
140155impl < ' a > IntoIterator for & ' a mut Vary {
141- type Item = & ' a mut VaryDirective ;
156+ type Item = & ' a mut HeaderName ;
142157 type IntoIter = IterMut < ' a > ;
143158
144159 #[ inline]
@@ -150,11 +165,11 @@ impl<'a> IntoIterator for &'a mut Vary {
150165/// A borrowing iterator over entries in `Vary`.
151166#[ derive( Debug ) ]
152167pub struct IntoIter {
153- inner : std:: vec:: IntoIter < VaryDirective > ,
168+ inner : std:: vec:: IntoIter < HeaderName > ,
154169}
155170
156171impl Iterator for IntoIter {
157- type Item = VaryDirective ;
172+ type Item = HeaderName ;
158173
159174 fn next ( & mut self ) -> Option < Self :: Item > {
160175 self . inner . next ( )
@@ -169,11 +184,11 @@ impl Iterator for IntoIter {
169184/// A lending iterator over entries in `Vary`.
170185#[ derive( Debug ) ]
171186pub struct Iter < ' a > {
172- inner : slice:: Iter < ' a , VaryDirective > ,
187+ inner : slice:: Iter < ' a , HeaderName > ,
173188}
174189
175190impl < ' a > Iterator for Iter < ' a > {
176- type Item = & ' a VaryDirective ;
191+ type Item = & ' a HeaderName ;
177192
178193 fn next ( & mut self ) -> Option < Self :: Item > {
179194 self . inner . next ( )
@@ -188,11 +203,11 @@ impl<'a> Iterator for Iter<'a> {
188203/// A mutable iterator over entries in `Vary`.
189204#[ derive( Debug ) ]
190205pub struct IterMut < ' a > {
191- inner : slice:: IterMut < ' a , VaryDirective > ,
206+ inner : slice:: IterMut < ' a , HeaderName > ,
192207}
193208
194209impl < ' a > Iterator for IterMut < ' a > {
195- type Item = & ' a mut VaryDirective ;
210+ type Item = & ' a mut HeaderName ;
196211
197212 fn next ( & mut self ) -> Option < Self :: Item > {
198213 self . inner . next ( )
@@ -242,4 +257,20 @@ mod test {
242257 assert_eq ! ( entries. next( ) . unwrap( ) , "Accept-Encoding" ) ;
243258 Ok ( ( ) )
244259 }
260+
261+ #[ test]
262+ fn wildcard ( ) -> crate :: Result < ( ) > {
263+ let mut entries = Vary :: new ( ) ;
264+ entries. push ( "User-Agent" ) ?;
265+ entries. push ( "*" ) ?;
266+
267+ let mut res = Response :: new ( 200 ) ;
268+ entries. apply ( & mut res) ;
269+
270+ let entries = Vary :: from_headers ( res) ?. unwrap ( ) ;
271+ assert_eq ! ( entries. wildcard( ) , true ) ;
272+ let mut entries = entries. iter ( ) ;
273+ assert_eq ! ( entries. next( ) . unwrap( ) , "User-Agent" ) ;
274+ Ok ( ( ) )
275+ }
245276}
0 commit comments