@@ -8,18 +8,35 @@ use crate::headers::HeaderValue;
88use std:: {
99 borrow:: Cow ,
1010 fmt:: { self , Display } ,
11+ slice,
1112 str:: FromStr ,
1213} ;
1314
1415/// An RFC 4647 language range.
1516#[ derive( Debug , Clone , PartialEq ) ]
1617pub struct LanguageRange {
17- pub ( crate ) tags : Vec < Cow < ' static , str > > ,
18+ pub ( crate ) subtags : Vec < Cow < ' static , str > > ,
19+ }
20+
21+ impl LanguageRange {
22+ /// An iterator visiting all entries.
23+ pub fn iter ( & self ) -> Iter < ' _ > {
24+ Iter {
25+ inner : self . subtags . iter ( ) ,
26+ }
27+ }
28+
29+ /// An iterator visiting all entries.
30+ pub fn iter_mut ( & mut self ) -> IterMut < ' _ > {
31+ IterMut {
32+ inner : self . subtags . iter_mut ( ) ,
33+ }
34+ }
1835}
1936
2037impl Display for LanguageRange {
2138 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
22- let mut tags = self . tags . iter ( ) ;
39+ let mut tags = self . subtags . iter ( ) ;
2340 if let Some ( tag) = tags. next ( ) {
2441 write ! ( f, "{}" , tag) ?;
2542
@@ -31,6 +48,95 @@ impl Display for LanguageRange {
3148 }
3249}
3350
51+ /// A borrowing iterator over entries in `LanguageRange`.
52+ #[ derive( Debug ) ]
53+ pub struct IntoIter {
54+ inner : std:: vec:: IntoIter < Cow < ' static , str > > ,
55+ }
56+
57+ impl Iterator for IntoIter {
58+ type Item = Cow < ' static , str > ;
59+
60+ fn next ( & mut self ) -> Option < Self :: Item > {
61+ self . inner . next ( )
62+ }
63+
64+ #[ inline]
65+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
66+ self . inner . size_hint ( )
67+ }
68+ }
69+
70+ /// A lending iterator over entries in `LanguageRange`.
71+ #[ derive( Debug ) ]
72+ pub struct Iter < ' a > {
73+ inner : slice:: Iter < ' a , Cow < ' static , str > > ,
74+ }
75+
76+ impl < ' a > Iterator for Iter < ' a > {
77+ type Item = & ' a Cow < ' static , str > ;
78+
79+ fn next ( & mut self ) -> Option < Self :: Item > {
80+ self . inner . next ( )
81+ }
82+
83+ #[ inline]
84+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
85+ self . inner . size_hint ( )
86+ }
87+ }
88+
89+ /// A mutable iterator over entries in `LanguageRange`.
90+ #[ derive( Debug ) ]
91+ pub struct IterMut < ' a > {
92+ inner : slice:: IterMut < ' a , Cow < ' static , str > > ,
93+ }
94+
95+ impl < ' a > Iterator for IterMut < ' a > {
96+ type Item = & ' a mut Cow < ' static , str > ;
97+
98+ fn next ( & mut self ) -> Option < Self :: Item > {
99+ self . inner . next ( )
100+ }
101+
102+ #[ inline]
103+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
104+ self . inner . size_hint ( )
105+ }
106+ }
107+
108+ impl IntoIterator for LanguageRange {
109+ type Item = Cow < ' static , str > ;
110+ type IntoIter = IntoIter ;
111+
112+ #[ inline]
113+ fn into_iter ( self ) -> Self :: IntoIter {
114+ IntoIter {
115+ inner : self . subtags . into_iter ( ) ,
116+ }
117+ }
118+ }
119+
120+ impl < ' a > IntoIterator for & ' a LanguageRange {
121+ type Item = & ' a Cow < ' static , str > ;
122+ type IntoIter = Iter < ' a > ;
123+
124+ #[ inline]
125+ fn into_iter ( self ) -> Self :: IntoIter {
126+ self . iter ( )
127+ }
128+ }
129+
130+ impl < ' a > IntoIterator for & ' a mut LanguageRange {
131+ type Item = & ' a mut Cow < ' static , str > ;
132+ type IntoIter = IterMut < ' a > ;
133+
134+ #[ inline]
135+ fn into_iter ( self ) -> Self :: IntoIter {
136+ self . iter_mut ( )
137+ }
138+ }
139+
34140impl From < LanguageRange > for HeaderValue {
35141 fn from ( language : LanguageRange ) -> Self {
36142 let s = language. to_string ( ) ;
@@ -51,3 +157,16 @@ impl<'a> From<&'a str> for LanguageRange {
51157 Self :: from_str ( value) . unwrap ( )
52158 }
53159}
160+
161+ #[ cfg( test) ]
162+ mod test {
163+ use super :: * ;
164+
165+ #[ test]
166+ fn test_iter ( ) -> crate :: Result < ( ) > {
167+ let range: LanguageRange = "en-CA" . parse ( ) . unwrap ( ) ;
168+ let subtags: Vec < _ > = range. iter ( ) . collect ( ) ;
169+ assert_eq ! ( & subtags, & [ "en" , "CA" ] ) ;
170+ Ok ( ( ) )
171+ }
172+ }
0 commit comments