1
1
//! Apply the HTTP method if the ETag matches.
2
2
3
- use crate :: conditional:: VaryDirective ;
4
3
use crate :: headers:: { HeaderName , HeaderValue , Headers , ToHeaderValues , VARY } ;
5
4
6
- use std:: convert:: TryInto ;
7
5
use std:: fmt:: { self , Debug , Write } ;
8
6
use std:: iter:: Iterator ;
9
7
use std:: option;
@@ -39,13 +37,14 @@ use std::str::FromStr;
39
37
/// # Ok(()) }
40
38
/// ```
41
39
pub struct Vary {
42
- entries : Vec < VaryDirective > ,
40
+ entries : Vec < HeaderName > ,
41
+ wildcard : bool ,
43
42
}
44
43
45
44
impl Vary {
46
45
/// Create a new instance of `Vary`.
47
46
pub fn new ( ) -> Self {
48
- Self { entries : vec ! [ ] }
47
+ Self { entries : vec ! [ ] , wildcard : false }
49
48
}
50
49
51
50
/// Create a new instance from headers.
@@ -56,14 +55,20 @@ impl Vary {
56
55
None => return Ok ( None ) ,
57
56
} ;
58
57
58
+ let mut wildcard = false ;
59
59
for value in headers {
60
60
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 ( ) ) ?;
62
67
entries. push ( entry) ;
63
68
}
64
69
}
65
70
66
- Ok ( Some ( Self { entries } ) )
71
+ Ok ( Some ( Self { entries, wildcard } ) )
67
72
}
68
73
69
74
/// Sets the `If-Match` header.
@@ -76,11 +81,21 @@ impl Vary {
76
81
VARY
77
82
}
78
83
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
+
79
94
/// Get the `HeaderValue`.
80
95
pub fn value ( & self ) -> HeaderValue {
81
96
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" ) ;
84
99
match n {
85
100
0 => write ! ( output, "{}" , directive) . unwrap ( ) ,
86
101
_ => write ! ( output, ", {}" , directive) . unwrap ( ) ,
@@ -94,9 +109,9 @@ impl Vary {
94
109
/// Push a directive into the list of entries.
95
110
pub fn push (
96
111
& mut self ,
97
- directive : impl TryInto < VaryDirective , Error = crate :: Error > ,
112
+ directive : impl Into < HeaderName > ,
98
113
) -> crate :: Result < ( ) > {
99
- self . entries . push ( directive. try_into ( ) ? ) ;
114
+ self . entries . push ( directive. into ( ) ) ;
100
115
Ok ( ( ) )
101
116
}
102
117
@@ -116,7 +131,7 @@ impl Vary {
116
131
}
117
132
118
133
impl IntoIterator for Vary {
119
- type Item = VaryDirective ;
134
+ type Item = HeaderName ;
120
135
type IntoIter = IntoIter ;
121
136
122
137
#[ inline]
@@ -128,7 +143,7 @@ impl IntoIterator for Vary {
128
143
}
129
144
130
145
impl < ' a > IntoIterator for & ' a Vary {
131
- type Item = & ' a VaryDirective ;
146
+ type Item = & ' a HeaderName ;
132
147
type IntoIter = Iter < ' a > ;
133
148
134
149
#[ inline]
@@ -138,7 +153,7 @@ impl<'a> IntoIterator for &'a Vary {
138
153
}
139
154
140
155
impl < ' a > IntoIterator for & ' a mut Vary {
141
- type Item = & ' a mut VaryDirective ;
156
+ type Item = & ' a mut HeaderName ;
142
157
type IntoIter = IterMut < ' a > ;
143
158
144
159
#[ inline]
@@ -150,11 +165,11 @@ impl<'a> IntoIterator for &'a mut Vary {
150
165
/// A borrowing iterator over entries in `Vary`.
151
166
#[ derive( Debug ) ]
152
167
pub struct IntoIter {
153
- inner : std:: vec:: IntoIter < VaryDirective > ,
168
+ inner : std:: vec:: IntoIter < HeaderName > ,
154
169
}
155
170
156
171
impl Iterator for IntoIter {
157
- type Item = VaryDirective ;
172
+ type Item = HeaderName ;
158
173
159
174
fn next ( & mut self ) -> Option < Self :: Item > {
160
175
self . inner . next ( )
@@ -169,11 +184,11 @@ impl Iterator for IntoIter {
169
184
/// A lending iterator over entries in `Vary`.
170
185
#[ derive( Debug ) ]
171
186
pub struct Iter < ' a > {
172
- inner : slice:: Iter < ' a , VaryDirective > ,
187
+ inner : slice:: Iter < ' a , HeaderName > ,
173
188
}
174
189
175
190
impl < ' a > Iterator for Iter < ' a > {
176
- type Item = & ' a VaryDirective ;
191
+ type Item = & ' a HeaderName ;
177
192
178
193
fn next ( & mut self ) -> Option < Self :: Item > {
179
194
self . inner . next ( )
@@ -188,11 +203,11 @@ impl<'a> Iterator for Iter<'a> {
188
203
/// A mutable iterator over entries in `Vary`.
189
204
#[ derive( Debug ) ]
190
205
pub struct IterMut < ' a > {
191
- inner : slice:: IterMut < ' a , VaryDirective > ,
206
+ inner : slice:: IterMut < ' a , HeaderName > ,
192
207
}
193
208
194
209
impl < ' a > Iterator for IterMut < ' a > {
195
- type Item = & ' a mut VaryDirective ;
210
+ type Item = & ' a mut HeaderName ;
196
211
197
212
fn next ( & mut self ) -> Option < Self :: Item > {
198
213
self . inner . next ( )
@@ -242,4 +257,20 @@ mod test {
242
257
assert_eq ! ( entries. next( ) . unwrap( ) , "Accept-Encoding" ) ;
243
258
Ok ( ( ) )
244
259
}
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
+ }
245
276
}
0 commit comments