1use crate::{
2 error::{DecodeUtf16Error, DecodeUtf32Error},
3 iter::{DecodeUtf16, DecodeUtf16Lossy, DecodeUtf32, DecodeUtf32Lossy},
4};
5#[allow(unused_imports)]
6use core::{
7 iter::{Copied, DoubleEndedIterator, ExactSizeIterator, FusedIterator},
8 slice::Iter,
9};
10
11#[derive(Clone)]
15pub struct CharsUtf16<'a> {
16 inner: DecodeUtf16<Copied<Iter<'a, u16>>>,
17}
18
19impl<'a> CharsUtf16<'a> {
20 pub(crate) fn new(s: &'a [u16]) -> Self {
21 Self {
22 inner: crate::decode_utf16(s.iter().copied()),
23 }
24 }
25}
26
27impl Iterator for CharsUtf16<'_> {
28 type Item = Result<char, DecodeUtf16Error>;
29
30 #[inline]
31 fn next(&mut self) -> Option<Self::Item> {
32 self.inner.next()
33 }
34
35 #[inline]
36 fn size_hint(&self) -> (usize, Option<usize>) {
37 self.inner.size_hint()
38 }
39}
40
41impl FusedIterator for CharsUtf16<'_> {}
42
43impl DoubleEndedIterator for CharsUtf16<'_> {
44 #[inline]
45 fn next_back(&mut self) -> Option<Self::Item> {
46 self.inner.next_back()
47 }
48}
49
50impl core::fmt::Debug for CharsUtf16<'_> {
51 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
52 crate::debug_fmt_utf16_iter(self.clone(), f)
53 }
54}
55
56#[derive(Clone)]
60pub struct CharsUtf32<'a> {
61 inner: DecodeUtf32<Copied<Iter<'a, u32>>>,
62}
63
64impl<'a> CharsUtf32<'a> {
65 pub(crate) fn new(s: &'a [u32]) -> Self {
66 Self {
67 inner: crate::decode_utf32(s.iter().copied()),
68 }
69 }
70}
71
72impl Iterator for CharsUtf32<'_> {
73 type Item = Result<char, DecodeUtf32Error>;
74
75 #[inline]
76 fn next(&mut self) -> Option<Self::Item> {
77 self.inner.next()
78 }
79
80 #[inline]
81 fn size_hint(&self) -> (usize, Option<usize>) {
82 self.inner.size_hint()
83 }
84}
85
86impl FusedIterator for CharsUtf32<'_> {}
87
88impl DoubleEndedIterator for CharsUtf32<'_> {
89 #[inline]
90 fn next_back(&mut self) -> Option<Self::Item> {
91 self.inner.next_back()
92 }
93}
94
95impl ExactSizeIterator for CharsUtf32<'_> {
96 #[inline]
97 fn len(&self) -> usize {
98 self.inner.len()
99 }
100}
101
102impl core::fmt::Debug for CharsUtf32<'_> {
103 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
104 crate::debug_fmt_utf32_iter(self.clone(), f)
105 }
106}
107
108#[derive(Clone)]
112pub struct CharsLossyUtf16<'a> {
113 iter: DecodeUtf16Lossy<Copied<Iter<'a, u16>>>,
114}
115
116impl<'a> CharsLossyUtf16<'a> {
117 pub(crate) fn new(s: &'a [u16]) -> Self {
118 Self {
119 iter: crate::decode_utf16_lossy(s.iter().copied()),
120 }
121 }
122}
123
124impl Iterator for CharsLossyUtf16<'_> {
125 type Item = char;
126
127 #[inline]
128 fn next(&mut self) -> Option<Self::Item> {
129 self.iter.next()
130 }
131
132 #[inline]
133 fn size_hint(&self) -> (usize, Option<usize>) {
134 self.iter.size_hint()
135 }
136}
137
138impl FusedIterator for CharsLossyUtf16<'_> {}
139
140impl DoubleEndedIterator for CharsLossyUtf16<'_> {
141 #[inline]
142 fn next_back(&mut self) -> Option<Self::Item> {
143 self.iter.next_back()
144 }
145}
146
147impl core::fmt::Debug for CharsLossyUtf16<'_> {
148 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
149 crate::debug_fmt_char_iter(self.clone(), f)
150 }
151}
152
153#[derive(Clone)]
157pub struct CharsLossyUtf32<'a> {
158 iter: DecodeUtf32Lossy<Copied<Iter<'a, u32>>>,
159}
160
161impl<'a> CharsLossyUtf32<'a> {
162 pub(crate) fn new(s: &'a [u32]) -> Self {
163 Self {
164 iter: crate::decode_utf32_lossy(s.iter().copied()),
165 }
166 }
167}
168
169impl Iterator for CharsLossyUtf32<'_> {
170 type Item = char;
171
172 #[inline]
173 fn next(&mut self) -> Option<Self::Item> {
174 self.iter.next()
175 }
176
177 #[inline]
178 fn size_hint(&self) -> (usize, Option<usize>) {
179 self.iter.size_hint()
180 }
181}
182
183impl FusedIterator for CharsLossyUtf32<'_> {}
184
185impl DoubleEndedIterator for CharsLossyUtf32<'_> {
186 #[inline]
187 fn next_back(&mut self) -> Option<Self::Item> {
188 self.iter.next_back()
189 }
190}
191
192impl ExactSizeIterator for CharsLossyUtf32<'_> {
193 #[inline]
194 fn len(&self) -> usize {
195 self.iter.len()
196 }
197}
198
199impl core::fmt::Debug for CharsLossyUtf32<'_> {
200 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
201 crate::debug_fmt_char_iter(self.clone(), f)
202 }
203}
204
205#[derive(Debug, Clone)]
210pub struct CharIndicesUtf16<'a> {
211 forward_offset: usize,
212 back_offset: usize,
213 iter: CharsUtf16<'a>,
214}
215
216impl<'a> CharIndicesUtf16<'a> {
217 pub(crate) fn new(s: &'a [u16]) -> Self {
218 Self {
219 forward_offset: 0,
220 back_offset: s.len(),
221 iter: CharsUtf16::new(s),
222 }
223 }
224
225 #[inline]
228 pub fn offset(&self) -> usize {
229 self.forward_offset
230 }
231}
232
233impl Iterator for CharIndicesUtf16<'_> {
234 type Item = (usize, Result<char, DecodeUtf16Error>);
235
236 fn next(&mut self) -> Option<Self::Item> {
237 match self.iter.next() {
238 Some(Ok(c)) => {
239 let idx = self.forward_offset;
240 self.forward_offset += c.len_utf16();
241 Some((idx, Ok(c)))
242 }
243 Some(Err(e)) => {
244 let idx = self.forward_offset;
245 self.forward_offset += 1;
246 Some((idx, Err(e)))
247 }
248 None => None,
249 }
250 }
251
252 #[inline]
253 fn size_hint(&self) -> (usize, Option<usize>) {
254 self.iter.size_hint()
255 }
256}
257
258impl FusedIterator for CharIndicesUtf16<'_> {}
259
260impl DoubleEndedIterator for CharIndicesUtf16<'_> {
261 #[inline]
262 fn next_back(&mut self) -> Option<Self::Item> {
263 match self.iter.next_back() {
264 Some(Ok(c)) => {
265 self.back_offset -= c.len_utf16();
266 Some((self.back_offset, Ok(c)))
267 }
268 Some(Err(e)) => {
269 self.back_offset -= 1;
270 Some((self.back_offset, Err(e)))
271 }
272 None => None,
273 }
274 }
275}
276
277#[derive(Debug, Clone)]
282pub struct CharIndicesUtf32<'a> {
283 forward_offset: usize,
284 back_offset: usize,
285 iter: CharsUtf32<'a>,
286}
287
288impl<'a> CharIndicesUtf32<'a> {
289 pub(crate) fn new(s: &'a [u32]) -> Self {
290 Self {
291 forward_offset: 0,
292 back_offset: s.len(),
293 iter: CharsUtf32::new(s),
294 }
295 }
296
297 #[inline]
300 pub fn offset(&self) -> usize {
301 self.forward_offset
302 }
303}
304
305impl Iterator for CharIndicesUtf32<'_> {
306 type Item = (usize, Result<char, DecodeUtf32Error>);
307
308 fn next(&mut self) -> Option<Self::Item> {
309 match self.iter.next() {
310 Some(Ok(c)) => {
311 let idx = self.forward_offset;
312 self.forward_offset += 1;
313 Some((idx, Ok(c)))
314 }
315 Some(Err(e)) => {
316 let idx = self.forward_offset;
317 self.forward_offset += 1;
318 Some((idx, Err(e)))
319 }
320 None => None,
321 }
322 }
323
324 #[inline]
325 fn size_hint(&self) -> (usize, Option<usize>) {
326 self.iter.size_hint()
327 }
328}
329
330impl FusedIterator for CharIndicesUtf32<'_> {}
331
332impl DoubleEndedIterator for CharIndicesUtf32<'_> {
333 #[inline]
334 fn next_back(&mut self) -> Option<Self::Item> {
335 match self.iter.next_back() {
336 Some(Ok(c)) => {
337 self.back_offset -= 1;
338 Some((self.back_offset, Ok(c)))
339 }
340 Some(Err(e)) => {
341 self.back_offset -= 1;
342 Some((self.back_offset, Err(e)))
343 }
344 None => None,
345 }
346 }
347}
348
349impl ExactSizeIterator for CharIndicesUtf32<'_> {
350 #[inline]
351 fn len(&self) -> usize {
352 self.iter.len()
353 }
354}
355
356#[derive(Debug, Clone)]
361pub struct CharIndicesLossyUtf16<'a> {
362 forward_offset: usize,
363 back_offset: usize,
364 iter: CharsLossyUtf16<'a>,
365}
366
367impl<'a> CharIndicesLossyUtf16<'a> {
368 pub(crate) fn new(s: &'a [u16]) -> Self {
369 Self {
370 forward_offset: 0,
371 back_offset: s.len(),
372 iter: CharsLossyUtf16::new(s),
373 }
374 }
375
376 #[inline]
379 pub fn offset(&self) -> usize {
380 self.forward_offset
381 }
382}
383
384impl Iterator for CharIndicesLossyUtf16<'_> {
385 type Item = (usize, char);
386
387 #[inline]
388 fn next(&mut self) -> Option<Self::Item> {
389 match self.iter.next() {
390 Some(c) => {
391 let idx = self.forward_offset;
392 self.forward_offset += c.len_utf16();
393 Some((idx, c))
394 }
395 None => None,
396 }
397 }
398
399 #[inline]
400 fn size_hint(&self) -> (usize, Option<usize>) {
401 self.iter.size_hint()
402 }
403}
404
405impl FusedIterator for CharIndicesLossyUtf16<'_> {}
406
407impl DoubleEndedIterator for CharIndicesLossyUtf16<'_> {
408 #[inline]
409 fn next_back(&mut self) -> Option<Self::Item> {
410 match self.iter.next_back() {
411 Some(c) => {
412 self.back_offset -= c.len_utf16();
413 Some((self.back_offset, c))
414 }
415 None => None,
416 }
417 }
418}
419
420#[derive(Debug, Clone)]
425pub struct CharIndicesLossyUtf32<'a> {
426 forward_offset: usize,
427 back_offset: usize,
428 iter: CharsLossyUtf32<'a>,
429}
430
431impl<'a> CharIndicesLossyUtf32<'a> {
432 pub(crate) fn new(s: &'a [u32]) -> Self {
433 Self {
434 forward_offset: 0,
435 back_offset: s.len(),
436 iter: CharsLossyUtf32::new(s),
437 }
438 }
439
440 #[inline]
443 pub fn offset(&self) -> usize {
444 self.forward_offset
445 }
446}
447
448impl Iterator for CharIndicesLossyUtf32<'_> {
449 type Item = (usize, char);
450
451 #[inline]
452 fn next(&mut self) -> Option<Self::Item> {
453 match self.iter.next() {
454 Some(c) => {
455 let idx = self.forward_offset;
456 self.forward_offset += 1;
457 Some((idx, c))
458 }
459 None => None,
460 }
461 }
462
463 #[inline]
464 fn size_hint(&self) -> (usize, Option<usize>) {
465 self.iter.size_hint()
466 }
467}
468
469impl FusedIterator for CharIndicesLossyUtf32<'_> {}
470
471impl DoubleEndedIterator for CharIndicesLossyUtf32<'_> {
472 #[inline]
473 fn next_back(&mut self) -> Option<Self::Item> {
474 match self.iter.next_back() {
475 Some(c) => {
476 self.back_offset -= 1;
477 Some((self.back_offset, c))
478 }
479 None => None,
480 }
481 }
482}
483
484impl ExactSizeIterator for CharIndicesLossyUtf32<'_> {
485 #[inline]
486 fn len(&self) -> usize {
487 self.iter.len()
488 }
489}