@@ -4,6 +4,7 @@ use crate::content::LanguageProposal;
4
4
use crate :: headers:: { Header , HeaderValue , Headers , ACCEPT_LANGUAGE } ;
5
5
6
6
use std:: fmt:: { self , Debug , Write } ;
7
+ use std:: slice;
7
8
8
9
/// Client header advertising which languages the client is able to understand.
9
10
pub struct AcceptLanguage {
@@ -48,6 +49,35 @@ impl AcceptLanguage {
48
49
49
50
Ok ( Some ( Self { wildcard, entries } ) )
50
51
}
52
+
53
+ /// Push a directive into the list of entries.
54
+ pub fn push ( & mut self , prop : impl Into < LanguageProposal > ) {
55
+ self . entries . push ( prop. into ( ) )
56
+ }
57
+
58
+ /// Returns `true` if a wildcard directive was passed.
59
+ pub fn wildcard ( & self ) -> bool {
60
+ self . wildcard
61
+ }
62
+
63
+ /// Set the wildcard directive.
64
+ pub fn set_wildcard ( & mut self , wildcard : bool ) {
65
+ self . wildcard = wildcard
66
+ }
67
+
68
+ /// An iterator visiting all entries.
69
+ pub fn iter ( & self ) -> Iter < ' _ > {
70
+ Iter {
71
+ inner : self . entries . iter ( ) ,
72
+ }
73
+ }
74
+
75
+ /// An iterator visiting all entries.
76
+ pub fn iter_mut ( & mut self ) -> IterMut < ' _ > {
77
+ IterMut {
78
+ inner : self . entries . iter_mut ( ) ,
79
+ }
80
+ }
51
81
}
52
82
53
83
impl Header for AcceptLanguage {
@@ -77,6 +107,63 @@ impl Header for AcceptLanguage {
77
107
}
78
108
}
79
109
110
+ /// A borrowing iterator over entries in `AcceptLanguage`.
111
+ #[ derive( Debug ) ]
112
+ pub struct IntoIter {
113
+ inner : std:: vec:: IntoIter < LanguageProposal > ,
114
+ }
115
+
116
+ impl Iterator for IntoIter {
117
+ type Item = LanguageProposal ;
118
+
119
+ fn next ( & mut self ) -> Option < Self :: Item > {
120
+ self . inner . next ( )
121
+ }
122
+
123
+ #[ inline]
124
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
125
+ self . inner . size_hint ( )
126
+ }
127
+ }
128
+
129
+ /// A lending iterator over entries in `AcceptLanguage`.
130
+ #[ derive( Debug ) ]
131
+ pub struct Iter < ' a > {
132
+ inner : slice:: Iter < ' a , LanguageProposal > ,
133
+ }
134
+
135
+ impl < ' a > Iterator for Iter < ' a > {
136
+ type Item = & ' a LanguageProposal ;
137
+
138
+ fn next ( & mut self ) -> Option < Self :: Item > {
139
+ self . inner . next ( )
140
+ }
141
+
142
+ #[ inline]
143
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
144
+ self . inner . size_hint ( )
145
+ }
146
+ }
147
+
148
+ /// A mutable iterator over entries in `AcceptLanguage`.
149
+ #[ derive( Debug ) ]
150
+ pub struct IterMut < ' a > {
151
+ inner : slice:: IterMut < ' a , LanguageProposal > ,
152
+ }
153
+
154
+ impl < ' a > Iterator for IterMut < ' a > {
155
+ type Item = & ' a mut LanguageProposal ;
156
+
157
+ fn next ( & mut self ) -> Option < Self :: Item > {
158
+ self . inner . next ( )
159
+ }
160
+
161
+ #[ inline]
162
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
163
+ self . inner . size_hint ( )
164
+ }
165
+ }
166
+
80
167
impl Debug for AcceptLanguage {
81
168
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
82
169
let mut list = f. debug_list ( ) ;
@@ -86,3 +173,68 @@ impl Debug for AcceptLanguage {
86
173
list. finish ( )
87
174
}
88
175
}
176
+
177
+ impl IntoIterator for AcceptLanguage {
178
+ type Item = LanguageProposal ;
179
+ type IntoIter = IntoIter ;
180
+
181
+ #[ inline]
182
+ fn into_iter ( self ) -> Self :: IntoIter {
183
+ IntoIter {
184
+ inner : self . entries . into_iter ( ) ,
185
+ }
186
+ }
187
+ }
188
+
189
+ impl < ' a > IntoIterator for & ' a AcceptLanguage {
190
+ type Item = & ' a LanguageProposal ;
191
+ type IntoIter = Iter < ' a > ;
192
+
193
+ #[ inline]
194
+ fn into_iter ( self ) -> Self :: IntoIter {
195
+ self . iter ( )
196
+ }
197
+ }
198
+
199
+ impl < ' a > IntoIterator for & ' a mut AcceptLanguage {
200
+ type Item = & ' a mut LanguageProposal ;
201
+ type IntoIter = IterMut < ' a > ;
202
+
203
+ #[ inline]
204
+ fn into_iter ( self ) -> Self :: IntoIter {
205
+ self . iter_mut ( )
206
+ }
207
+ }
208
+
209
+ #[ cfg( test) ]
210
+ mod test {
211
+ use super :: * ;
212
+ use crate :: Response ;
213
+
214
+ #[ test]
215
+ fn smoke ( ) -> crate :: Result < ( ) > {
216
+ let lang = LanguageProposal :: new ( "en-CA" , Some ( 1.0 ) ) . unwrap ( ) ;
217
+ let mut accept = AcceptLanguage :: new ( ) ;
218
+ accept. push ( lang. clone ( ) ) ;
219
+
220
+ let mut headers = Response :: new ( 200 ) ;
221
+ accept. apply_header ( & mut headers) ;
222
+
223
+ let accept = AcceptLanguage :: from_headers ( headers) ?. unwrap ( ) ;
224
+ assert_eq ! ( accept. iter( ) . next( ) . unwrap( ) , & lang) ;
225
+ Ok ( ( ) )
226
+ }
227
+
228
+ #[ test]
229
+ fn wildcard ( ) -> crate :: Result < ( ) > {
230
+ let mut accept = AcceptLanguage :: new ( ) ;
231
+ accept. set_wildcard ( true ) ;
232
+
233
+ let mut headers = Response :: new ( 200 ) ;
234
+ accept. apply_header ( & mut headers) ;
235
+
236
+ let accept = AcceptLanguage :: from_headers ( headers) ?. unwrap ( ) ;
237
+ assert ! ( accept. wildcard( ) ) ;
238
+ Ok ( ( ) )
239
+ }
240
+ }
0 commit comments