@@ -4,6 +4,7 @@ use crate::content::LanguageProposal;
44use crate :: headers:: { Header , HeaderValue , Headers , ACCEPT_LANGUAGE } ;
55
66use std:: fmt:: { self , Debug , Write } ;
7+ use std:: slice;
78
89/// Client header advertising which languages the client is able to understand.
910pub struct AcceptLanguage {
@@ -48,6 +49,35 @@ impl AcceptLanguage {
4849
4950 Ok ( Some ( Self { wildcard, entries } ) )
5051 }
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+ }
5181}
5282
5383impl Header for AcceptLanguage {
@@ -77,6 +107,63 @@ impl Header for AcceptLanguage {
77107 }
78108}
79109
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+
80167impl Debug for AcceptLanguage {
81168 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
82169 let mut list = f. debug_list ( ) ;
@@ -86,3 +173,68 @@ impl Debug for AcceptLanguage {
86173 list. finish ( )
87174 }
88175}
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