@@ -8,18 +8,35 @@ use crate::headers::HeaderValue;
8
8
use std:: {
9
9
borrow:: Cow ,
10
10
fmt:: { self , Display } ,
11
+ slice,
11
12
str:: FromStr ,
12
13
} ;
13
14
14
15
/// An RFC 4647 language range.
15
16
#[ derive( Debug , Clone , PartialEq ) ]
16
17
pub 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
+ }
18
35
}
19
36
20
37
impl Display for LanguageRange {
21
38
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
22
- let mut tags = self . tags . iter ( ) ;
39
+ let mut tags = self . subtags . iter ( ) ;
23
40
if let Some ( tag) = tags. next ( ) {
24
41
write ! ( f, "{}" , tag) ?;
25
42
@@ -31,6 +48,95 @@ impl Display for LanguageRange {
31
48
}
32
49
}
33
50
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
+
34
140
impl From < LanguageRange > for HeaderValue {
35
141
fn from ( language : LanguageRange ) -> Self {
36
142
let s = language. to_string ( ) ;
@@ -51,3 +157,16 @@ impl<'a> From<&'a str> for LanguageRange {
51
157
Self :: from_str ( value) . unwrap ( )
52
158
}
53
159
}
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