1use super::Utf8CharsWithTrie;
21use super::Utf8CharsWithTrieDefaultForAscii;
22use core::iter::FusedIterator;
23
24use icu_collections::codepointtrie::AbstractCodePointTrie;
25use icu_collections::codepointtrie::TrieValue;
26use icu_collections::codepointtrie::WithTrie;
27
28#[derive(Debug)]
30#[must_use = "iterators are lazy and do nothing unless consumed"]
31pub struct Utf8CharIndicesWithTrie<'slice, 'trie, T, V>
32where
33 V: TrieValue,
34 T: AbstractCodePointTrie<'trie, V>,
35{
36 front_offset: usize,
37 iter: Utf8CharsWithTrie<'slice, 'trie, T, V>,
38}
39
40impl<'slice, 'trie, T, V> Clone for Utf8CharIndicesWithTrie<'slice, 'trie, T, V>
41where
42 V: TrieValue,
43 T: AbstractCodePointTrie<'trie, V>,
44{
45 #[inline]
46 fn clone(&self) -> Self {
47 Self {
48 front_offset: self.front_offset,
49 iter: self.iter.clone(),
50 }
51 }
52}
53
54impl<'slice, 'trie, T, V> WithTrie<'trie, T, V> for Utf8CharIndicesWithTrie<'slice, 'trie, T, V>
55where
56 V: TrieValue,
57 T: AbstractCodePointTrie<'trie, V>,
58{
59 #[inline]
60 fn trie(&self) -> &'trie T {
61 self.iter.trie()
62 }
63}
64
65impl<'slice, 'trie, T, V> Iterator for Utf8CharIndicesWithTrie<'slice, 'trie, T, V>
66where
67 V: TrieValue,
68 T: AbstractCodePointTrie<'trie, V>,
69{
70 type Item = (usize, char, V);
71
72 #[inline]
73 fn next(&mut self) -> Option<Self::Item> {
74 let pre_len = self.as_slice().len();
75 match self.iter.next() {
76 None => None,
77 Some((ch, v)) => {
78 let index = self.front_offset;
79 let len = self.as_slice().len();
80 self.front_offset += pre_len - len;
81 Some((index, ch, v))
82 }
83 }
84 }
85
86 #[inline]
87 fn count(self) -> usize {
88 self.iter.count()
89 }
90
91 #[inline]
92 fn size_hint(&self) -> (usize, Option<usize>) {
93 self.iter.size_hint()
94 }
95
96 #[inline]
97 fn last(mut self) -> Option<Self::Item> {
98 self.next_back()
100 }
101}
102
103impl<'slice, 'trie, T, V> DoubleEndedIterator for Utf8CharIndicesWithTrie<'slice, 'trie, T, V>
104where
105 V: TrieValue,
106 T: AbstractCodePointTrie<'trie, V>,
107{
108 #[inline]
109 fn next_back(&mut self) -> Option<Self::Item> {
110 self.iter.next_back().map(|(ch, v)| {
111 let index = self.front_offset + self.as_slice().len();
112 (index, ch, v)
113 })
114 }
115}
116
117impl<'slice, 'trie, T, V> FusedIterator for Utf8CharIndicesWithTrie<'slice, 'trie, T, V>
118where
119 V: TrieValue,
120 T: AbstractCodePointTrie<'trie, V>,
121{
122}
123
124impl<'slice, 'trie, T, V> Utf8CharIndicesWithTrie<'slice, 'trie, T, V>
125where
126 V: TrieValue,
127 T: AbstractCodePointTrie<'trie, V>,
128{
129 #[inline(always)]
130 pub fn new(code_units: &'slice [u8], trie: &'trie T) -> Self {
132 Self {
133 front_offset: 0,
134 iter: Utf8CharsWithTrie::new(code_units, trie),
135 }
136 }
137
138 #[must_use]
143 #[inline]
144 pub fn as_slice(&self) -> &'slice [u8] {
145 self.iter.as_slice()
146 }
147
148 #[inline]
151 #[must_use]
152 pub fn offset(&self) -> usize {
153 self.front_offset
154 }
155}
156
157#[derive(Debug)]
161#[must_use = "iterators are lazy and do nothing unless consumed"]
162pub struct Utf8CharIndicesWithTrieDefaultForAscii<'slice, 'trie, T, V>
163where
164 V: TrieValue + Default,
165 T: AbstractCodePointTrie<'trie, V>,
166{
167 front_offset: usize,
168 iter: Utf8CharsWithTrieDefaultForAscii<'slice, 'trie, T, V>,
169}
170
171impl<'slice, 'trie, T, V> Clone for Utf8CharIndicesWithTrieDefaultForAscii<'slice, 'trie, T, V>
172where
173 V: TrieValue + Default,
174 T: AbstractCodePointTrie<'trie, V>,
175{
176 #[inline]
177 fn clone(&self) -> Self {
178 Self {
179 front_offset: self.front_offset,
180 iter: self.iter.clone(),
181 }
182 }
183}
184
185impl<'slice, 'trie, T, V> WithTrie<'trie, T, V>
186 for Utf8CharIndicesWithTrieDefaultForAscii<'slice, 'trie, T, V>
187where
188 V: TrieValue + Default,
189 T: AbstractCodePointTrie<'trie, V>,
190{
191 #[inline]
192 fn trie(&self) -> &'trie T {
193 self.iter.trie()
194 }
195}
196
197impl<'slice, 'trie, T, V> Iterator for Utf8CharIndicesWithTrieDefaultForAscii<'slice, 'trie, T, V>
198where
199 V: TrieValue + Default,
200 T: AbstractCodePointTrie<'trie, V>,
201{
202 type Item = (usize, char, V);
203
204 #[inline]
205 fn next(&mut self) -> Option<Self::Item> {
206 let pre_len = self.as_slice().len();
207 match self.iter.next() {
208 None => None,
209 Some((ch, v)) => {
210 let index = self.front_offset;
211 let len = self.as_slice().len();
212 self.front_offset += pre_len - len;
213 Some((index, ch, v))
214 }
215 }
216 }
217
218 #[inline]
219 fn count(self) -> usize {
220 self.iter.count()
221 }
222
223 #[inline]
224 fn size_hint(&self) -> (usize, Option<usize>) {
225 self.iter.size_hint()
226 }
227
228 #[inline]
229 fn last(mut self) -> Option<Self::Item> {
230 self.next_back()
232 }
233}
234
235impl<'slice, 'trie, T, V> DoubleEndedIterator
236 for Utf8CharIndicesWithTrieDefaultForAscii<'slice, 'trie, T, V>
237where
238 V: TrieValue + Default,
239 T: AbstractCodePointTrie<'trie, V>,
240{
241 #[inline]
242 fn next_back(&mut self) -> Option<Self::Item> {
243 self.iter.next_back().map(|(ch, v)| {
244 let index = self.front_offset + self.as_slice().len();
245 (index, ch, v)
246 })
247 }
248}
249
250impl<'slice, 'trie, T, V> FusedIterator
251 for Utf8CharIndicesWithTrieDefaultForAscii<'slice, 'trie, T, V>
252where
253 V: TrieValue + Default,
254 T: AbstractCodePointTrie<'trie, V>,
255{
256}
257
258impl<'slice, 'trie, T, V> Utf8CharIndicesWithTrieDefaultForAscii<'slice, 'trie, T, V>
259where
260 V: TrieValue + Default,
261 T: AbstractCodePointTrie<'trie, V>,
262{
263 #[inline(always)]
264 pub fn new(code_units: &'slice [u8], trie: &'trie T) -> Self {
266 Self {
267 front_offset: 0,
268 iter: Utf8CharsWithTrieDefaultForAscii::new(code_units, trie),
269 }
270 }
271
272 #[must_use]
277 #[inline]
278 pub fn as_slice(&self) -> &'slice [u8] {
279 self.iter.as_slice()
280 }
281
282 #[inline]
285 #[must_use]
286 pub fn offset(&self) -> usize {
287 self.front_offset
288 }
289}