]> git.proxmox.com Git - rustc.git/blob - library/core/src/str/iter.rs
New upstream version 1.57.0+dfsg1
[rustc.git] / library / core / src / str / iter.rs
1 //! Iterators for `str` methods.
2
3 use crate::char;
4 use crate::fmt::{self, Write};
5 use crate::iter::{Chain, FlatMap, Flatten};
6 use crate::iter::{Copied, Filter, FusedIterator, Map, TrustedLen};
7 use crate::iter::{TrustedRandomAccess, TrustedRandomAccessNoCoerce};
8 use crate::ops::Try;
9 use crate::option;
10 use crate::slice::{self, Split as SliceSplit};
11
12 use super::from_utf8_unchecked;
13 use super::pattern::Pattern;
14 use super::pattern::{DoubleEndedSearcher, ReverseSearcher, Searcher};
15 use super::validations::{next_code_point, next_code_point_reverse, utf8_is_cont_byte};
16 use super::LinesAnyMap;
17 use super::{BytesIsNotEmpty, UnsafeBytesToStr};
18 use super::{CharEscapeDebugContinue, CharEscapeDefault, CharEscapeUnicode};
19 use super::{IsAsciiWhitespace, IsNotEmpty, IsWhitespace};
20
21 /// An iterator over the [`char`]s of a string slice.
22 ///
23 ///
24 /// This struct is created by the [`chars`] method on [`str`].
25 /// See its documentation for more.
26 ///
27 /// [`char`]: prim@char
28 /// [`chars`]: str::chars
29 #[derive(Clone)]
30 #[stable(feature = "rust1", since = "1.0.0")]
31 pub struct Chars<'a> {
32 pub(super) iter: slice::Iter<'a, u8>,
33 }
34
35 #[stable(feature = "rust1", since = "1.0.0")]
36 impl<'a> Iterator for Chars<'a> {
37 type Item = char;
38
39 #[inline]
40 fn next(&mut self) -> Option<char> {
41 next_code_point(&mut self.iter).map(|ch| {
42 // SAFETY: `str` invariant says `ch` is a valid Unicode Scalar Value.
43 unsafe { char::from_u32_unchecked(ch) }
44 })
45 }
46
47 #[inline]
48 fn count(self) -> usize {
49 // length in `char` is equal to the number of non-continuation bytes
50 self.iter.filter(|&&byte| !utf8_is_cont_byte(byte)).count()
51 }
52
53 #[inline]
54 fn size_hint(&self) -> (usize, Option<usize>) {
55 let len = self.iter.len();
56 // `(len + 3)` can't overflow, because we know that the `slice::Iter`
57 // belongs to a slice in memory which has a maximum length of
58 // `isize::MAX` (that's well below `usize::MAX`).
59 ((len + 3) / 4, Some(len))
60 }
61
62 #[inline]
63 fn last(mut self) -> Option<char> {
64 // No need to go through the entire string.
65 self.next_back()
66 }
67 }
68
69 #[stable(feature = "chars_debug_impl", since = "1.38.0")]
70 impl fmt::Debug for Chars<'_> {
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 write!(f, "Chars(")?;
73 f.debug_list().entries(self.clone()).finish()?;
74 write!(f, ")")?;
75 Ok(())
76 }
77 }
78
79 #[stable(feature = "rust1", since = "1.0.0")]
80 impl<'a> DoubleEndedIterator for Chars<'a> {
81 #[inline]
82 fn next_back(&mut self) -> Option<char> {
83 next_code_point_reverse(&mut self.iter).map(|ch| {
84 // SAFETY: `str` invariant says `ch` is a valid Unicode Scalar Value.
85 unsafe { char::from_u32_unchecked(ch) }
86 })
87 }
88 }
89
90 #[stable(feature = "fused", since = "1.26.0")]
91 impl FusedIterator for Chars<'_> {}
92
93 impl<'a> Chars<'a> {
94 /// Views the underlying data as a subslice of the original data.
95 ///
96 /// This has the same lifetime as the original slice, and so the
97 /// iterator can continue to be used while this exists.
98 ///
99 /// # Examples
100 ///
101 /// ```
102 /// let mut chars = "abc".chars();
103 ///
104 /// assert_eq!(chars.as_str(), "abc");
105 /// chars.next();
106 /// assert_eq!(chars.as_str(), "bc");
107 /// chars.next();
108 /// chars.next();
109 /// assert_eq!(chars.as_str(), "");
110 /// ```
111 #[stable(feature = "iter_to_slice", since = "1.4.0")]
112 #[must_use]
113 #[inline]
114 pub fn as_str(&self) -> &'a str {
115 // SAFETY: `Chars` is only made from a str, which guarantees the iter is valid UTF-8.
116 unsafe { from_utf8_unchecked(self.iter.as_slice()) }
117 }
118 }
119
120 /// An iterator over the [`char`]s of a string slice, and their positions.
121 ///
122 /// This struct is created by the [`char_indices`] method on [`str`].
123 /// See its documentation for more.
124 ///
125 /// [`char`]: prim@char
126 /// [`char_indices`]: str::char_indices
127 #[derive(Clone, Debug)]
128 #[stable(feature = "rust1", since = "1.0.0")]
129 pub struct CharIndices<'a> {
130 pub(super) front_offset: usize,
131 pub(super) iter: Chars<'a>,
132 }
133
134 #[stable(feature = "rust1", since = "1.0.0")]
135 impl<'a> Iterator for CharIndices<'a> {
136 type Item = (usize, char);
137
138 #[inline]
139 fn next(&mut self) -> Option<(usize, char)> {
140 let pre_len = self.iter.iter.len();
141 match self.iter.next() {
142 None => None,
143 Some(ch) => {
144 let index = self.front_offset;
145 let len = self.iter.iter.len();
146 self.front_offset += pre_len - len;
147 Some((index, ch))
148 }
149 }
150 }
151
152 #[inline]
153 fn count(self) -> usize {
154 self.iter.count()
155 }
156
157 #[inline]
158 fn size_hint(&self) -> (usize, Option<usize>) {
159 self.iter.size_hint()
160 }
161
162 #[inline]
163 fn last(mut self) -> Option<(usize, char)> {
164 // No need to go through the entire string.
165 self.next_back()
166 }
167 }
168
169 #[stable(feature = "rust1", since = "1.0.0")]
170 impl<'a> DoubleEndedIterator for CharIndices<'a> {
171 #[inline]
172 fn next_back(&mut self) -> Option<(usize, char)> {
173 self.iter.next_back().map(|ch| {
174 let index = self.front_offset + self.iter.iter.len();
175 (index, ch)
176 })
177 }
178 }
179
180 #[stable(feature = "fused", since = "1.26.0")]
181 impl FusedIterator for CharIndices<'_> {}
182
183 impl<'a> CharIndices<'a> {
184 /// Views the underlying data as a subslice of the original data.
185 ///
186 /// This has the same lifetime as the original slice, and so the
187 /// iterator can continue to be used while this exists.
188 #[stable(feature = "iter_to_slice", since = "1.4.0")]
189 #[must_use]
190 #[inline]
191 pub fn as_str(&self) -> &'a str {
192 self.iter.as_str()
193 }
194
195 /// Returns the byte position of the next character, or the length
196 /// of the underlying string if there are no more characters.
197 ///
198 /// # Examples
199 ///
200 /// ```
201 /// #![feature(char_indices_offset)]
202 /// let mut chars = "a楽".char_indices();
203 ///
204 /// assert_eq!(chars.offset(), 0);
205 /// assert_eq!(chars.next(), Some((0, 'a')));
206 ///
207 /// assert_eq!(chars.offset(), 1);
208 /// assert_eq!(chars.next(), Some((1, '楽')));
209 ///
210 /// assert_eq!(chars.offset(), 4);
211 /// assert_eq!(chars.next(), None);
212 /// ```
213 #[inline]
214 #[unstable(feature = "char_indices_offset", issue = "83871")]
215 pub fn offset(&self) -> usize {
216 self.front_offset
217 }
218 }
219
220 /// An iterator over the bytes of a string slice.
221 ///
222 /// This struct is created by the [`bytes`] method on [`str`].
223 /// See its documentation for more.
224 ///
225 /// [`bytes`]: str::bytes
226 #[stable(feature = "rust1", since = "1.0.0")]
227 #[derive(Clone, Debug)]
228 pub struct Bytes<'a>(pub(super) Copied<slice::Iter<'a, u8>>);
229
230 #[stable(feature = "rust1", since = "1.0.0")]
231 impl Iterator for Bytes<'_> {
232 type Item = u8;
233
234 #[inline]
235 fn next(&mut self) -> Option<u8> {
236 self.0.next()
237 }
238
239 #[inline]
240 fn size_hint(&self) -> (usize, Option<usize>) {
241 self.0.size_hint()
242 }
243
244 #[inline]
245 fn count(self) -> usize {
246 self.0.count()
247 }
248
249 #[inline]
250 fn last(self) -> Option<Self::Item> {
251 self.0.last()
252 }
253
254 #[inline]
255 fn nth(&mut self, n: usize) -> Option<Self::Item> {
256 self.0.nth(n)
257 }
258
259 #[inline]
260 fn all<F>(&mut self, f: F) -> bool
261 where
262 F: FnMut(Self::Item) -> bool,
263 {
264 self.0.all(f)
265 }
266
267 #[inline]
268 fn any<F>(&mut self, f: F) -> bool
269 where
270 F: FnMut(Self::Item) -> bool,
271 {
272 self.0.any(f)
273 }
274
275 #[inline]
276 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
277 where
278 P: FnMut(&Self::Item) -> bool,
279 {
280 self.0.find(predicate)
281 }
282
283 #[inline]
284 fn position<P>(&mut self, predicate: P) -> Option<usize>
285 where
286 P: FnMut(Self::Item) -> bool,
287 {
288 self.0.position(predicate)
289 }
290
291 #[inline]
292 fn rposition<P>(&mut self, predicate: P) -> Option<usize>
293 where
294 P: FnMut(Self::Item) -> bool,
295 {
296 self.0.rposition(predicate)
297 }
298
299 #[inline]
300 #[doc(hidden)]
301 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> u8 {
302 // SAFETY: the caller must uphold the safety contract
303 // for `Iterator::__iterator_get_unchecked`.
304 unsafe { self.0.__iterator_get_unchecked(idx) }
305 }
306 }
307
308 #[stable(feature = "rust1", since = "1.0.0")]
309 impl DoubleEndedIterator for Bytes<'_> {
310 #[inline]
311 fn next_back(&mut self) -> Option<u8> {
312 self.0.next_back()
313 }
314
315 #[inline]
316 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
317 self.0.nth_back(n)
318 }
319
320 #[inline]
321 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
322 where
323 P: FnMut(&Self::Item) -> bool,
324 {
325 self.0.rfind(predicate)
326 }
327 }
328
329 #[stable(feature = "rust1", since = "1.0.0")]
330 impl ExactSizeIterator for Bytes<'_> {
331 #[inline]
332 fn len(&self) -> usize {
333 self.0.len()
334 }
335
336 #[inline]
337 fn is_empty(&self) -> bool {
338 self.0.is_empty()
339 }
340 }
341
342 #[stable(feature = "fused", since = "1.26.0")]
343 impl FusedIterator for Bytes<'_> {}
344
345 #[unstable(feature = "trusted_len", issue = "37572")]
346 unsafe impl TrustedLen for Bytes<'_> {}
347
348 #[doc(hidden)]
349 #[unstable(feature = "trusted_random_access", issue = "none")]
350 unsafe impl TrustedRandomAccess for Bytes<'_> {}
351
352 #[doc(hidden)]
353 #[unstable(feature = "trusted_random_access", issue = "none")]
354 unsafe impl TrustedRandomAccessNoCoerce for Bytes<'_> {
355 const MAY_HAVE_SIDE_EFFECT: bool = false;
356 }
357
358 /// This macro generates a Clone impl for string pattern API
359 /// wrapper types of the form X<'a, P>
360 macro_rules! derive_pattern_clone {
361 (clone $t:ident with |$s:ident| $e:expr) => {
362 impl<'a, P> Clone for $t<'a, P>
363 where
364 P: Pattern<'a, Searcher: Clone>,
365 {
366 fn clone(&self) -> Self {
367 let $s = self;
368 $e
369 }
370 }
371 };
372 }
373
374 /// This macro generates two public iterator structs
375 /// wrapping a private internal one that makes use of the `Pattern` API.
376 ///
377 /// For all patterns `P: Pattern<'a>` the following items will be
378 /// generated (generics omitted):
379 ///
380 /// struct $forward_iterator($internal_iterator);
381 /// struct $reverse_iterator($internal_iterator);
382 ///
383 /// impl Iterator for $forward_iterator
384 /// { /* internal ends up calling Searcher::next_match() */ }
385 ///
386 /// impl DoubleEndedIterator for $forward_iterator
387 /// where P::Searcher: DoubleEndedSearcher
388 /// { /* internal ends up calling Searcher::next_match_back() */ }
389 ///
390 /// impl Iterator for $reverse_iterator
391 /// where P::Searcher: ReverseSearcher
392 /// { /* internal ends up calling Searcher::next_match_back() */ }
393 ///
394 /// impl DoubleEndedIterator for $reverse_iterator
395 /// where P::Searcher: DoubleEndedSearcher
396 /// { /* internal ends up calling Searcher::next_match() */ }
397 ///
398 /// The internal one is defined outside the macro, and has almost the same
399 /// semantic as a DoubleEndedIterator by delegating to `pattern::Searcher` and
400 /// `pattern::ReverseSearcher` for both forward and reverse iteration.
401 ///
402 /// "Almost", because a `Searcher` and a `ReverseSearcher` for a given
403 /// `Pattern` might not return the same elements, so actually implementing
404 /// `DoubleEndedIterator` for it would be incorrect.
405 /// (See the docs in `str::pattern` for more details)
406 ///
407 /// However, the internal struct still represents a single ended iterator from
408 /// either end, and depending on pattern is also a valid double ended iterator,
409 /// so the two wrapper structs implement `Iterator`
410 /// and `DoubleEndedIterator` depending on the concrete pattern type, leading
411 /// to the complex impls seen above.
412 macro_rules! generate_pattern_iterators {
413 {
414 // Forward iterator
415 forward:
416 $(#[$forward_iterator_attribute:meta])*
417 struct $forward_iterator:ident;
418
419 // Reverse iterator
420 reverse:
421 $(#[$reverse_iterator_attribute:meta])*
422 struct $reverse_iterator:ident;
423
424 // Stability of all generated items
425 stability:
426 $(#[$common_stability_attribute:meta])*
427
428 // Internal almost-iterator that is being delegated to
429 internal:
430 $internal_iterator:ident yielding ($iterty:ty);
431
432 // Kind of delegation - either single ended or double ended
433 delegate $($t:tt)*
434 } => {
435 $(#[$forward_iterator_attribute])*
436 $(#[$common_stability_attribute])*
437 pub struct $forward_iterator<'a, P: Pattern<'a>>(pub(super) $internal_iterator<'a, P>);
438
439 $(#[$common_stability_attribute])*
440 impl<'a, P> fmt::Debug for $forward_iterator<'a, P>
441 where
442 P: Pattern<'a, Searcher: fmt::Debug>,
443 {
444 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
445 f.debug_tuple(stringify!($forward_iterator))
446 .field(&self.0)
447 .finish()
448 }
449 }
450
451 $(#[$common_stability_attribute])*
452 impl<'a, P: Pattern<'a>> Iterator for $forward_iterator<'a, P> {
453 type Item = $iterty;
454
455 #[inline]
456 fn next(&mut self) -> Option<$iterty> {
457 self.0.next()
458 }
459 }
460
461 $(#[$common_stability_attribute])*
462 impl<'a, P> Clone for $forward_iterator<'a, P>
463 where
464 P: Pattern<'a, Searcher: Clone>,
465 {
466 fn clone(&self) -> Self {
467 $forward_iterator(self.0.clone())
468 }
469 }
470
471 $(#[$reverse_iterator_attribute])*
472 $(#[$common_stability_attribute])*
473 pub struct $reverse_iterator<'a, P: Pattern<'a>>(pub(super) $internal_iterator<'a, P>);
474
475 $(#[$common_stability_attribute])*
476 impl<'a, P> fmt::Debug for $reverse_iterator<'a, P>
477 where
478 P: Pattern<'a, Searcher: fmt::Debug>,
479 {
480 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
481 f.debug_tuple(stringify!($reverse_iterator))
482 .field(&self.0)
483 .finish()
484 }
485 }
486
487 $(#[$common_stability_attribute])*
488 impl<'a, P> Iterator for $reverse_iterator<'a, P>
489 where
490 P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
491 {
492 type Item = $iterty;
493
494 #[inline]
495 fn next(&mut self) -> Option<$iterty> {
496 self.0.next_back()
497 }
498 }
499
500 $(#[$common_stability_attribute])*
501 impl<'a, P> Clone for $reverse_iterator<'a, P>
502 where
503 P: Pattern<'a, Searcher: Clone>,
504 {
505 fn clone(&self) -> Self {
506 $reverse_iterator(self.0.clone())
507 }
508 }
509
510 #[stable(feature = "fused", since = "1.26.0")]
511 impl<'a, P: Pattern<'a>> FusedIterator for $forward_iterator<'a, P> {}
512
513 #[stable(feature = "fused", since = "1.26.0")]
514 impl<'a, P> FusedIterator for $reverse_iterator<'a, P>
515 where
516 P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
517 {}
518
519 generate_pattern_iterators!($($t)* with $(#[$common_stability_attribute])*,
520 $forward_iterator,
521 $reverse_iterator, $iterty);
522 };
523 {
524 double ended; with $(#[$common_stability_attribute:meta])*,
525 $forward_iterator:ident,
526 $reverse_iterator:ident, $iterty:ty
527 } => {
528 $(#[$common_stability_attribute])*
529 impl<'a, P> DoubleEndedIterator for $forward_iterator<'a, P>
530 where
531 P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,
532 {
533 #[inline]
534 fn next_back(&mut self) -> Option<$iterty> {
535 self.0.next_back()
536 }
537 }
538
539 $(#[$common_stability_attribute])*
540 impl<'a, P> DoubleEndedIterator for $reverse_iterator<'a, P>
541 where
542 P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,
543 {
544 #[inline]
545 fn next_back(&mut self) -> Option<$iterty> {
546 self.0.next()
547 }
548 }
549 };
550 {
551 single ended; with $(#[$common_stability_attribute:meta])*,
552 $forward_iterator:ident,
553 $reverse_iterator:ident, $iterty:ty
554 } => {}
555 }
556
557 derive_pattern_clone! {
558 clone SplitInternal
559 with |s| SplitInternal { matcher: s.matcher.clone(), ..*s }
560 }
561
562 pub(super) struct SplitInternal<'a, P: Pattern<'a>> {
563 pub(super) start: usize,
564 pub(super) end: usize,
565 pub(super) matcher: P::Searcher,
566 pub(super) allow_trailing_empty: bool,
567 pub(super) finished: bool,
568 }
569
570 impl<'a, P> fmt::Debug for SplitInternal<'a, P>
571 where
572 P: Pattern<'a, Searcher: fmt::Debug>,
573 {
574 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
575 f.debug_struct("SplitInternal")
576 .field("start", &self.start)
577 .field("end", &self.end)
578 .field("matcher", &self.matcher)
579 .field("allow_trailing_empty", &self.allow_trailing_empty)
580 .field("finished", &self.finished)
581 .finish()
582 }
583 }
584
585 impl<'a, P: Pattern<'a>> SplitInternal<'a, P> {
586 #[inline]
587 fn get_end(&mut self) -> Option<&'a str> {
588 if !self.finished && (self.allow_trailing_empty || self.end - self.start > 0) {
589 self.finished = true;
590 // SAFETY: `self.start` and `self.end` always lie on unicode boundaries.
591 unsafe {
592 let string = self.matcher.haystack().get_unchecked(self.start..self.end);
593 Some(string)
594 }
595 } else {
596 None
597 }
598 }
599
600 #[inline]
601 fn next(&mut self) -> Option<&'a str> {
602 if self.finished {
603 return None;
604 }
605
606 let haystack = self.matcher.haystack();
607 match self.matcher.next_match() {
608 // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries.
609 Some((a, b)) => unsafe {
610 let elt = haystack.get_unchecked(self.start..a);
611 self.start = b;
612 Some(elt)
613 },
614 None => self.get_end(),
615 }
616 }
617
618 #[inline]
619 fn next_inclusive(&mut self) -> Option<&'a str> {
620 if self.finished {
621 return None;
622 }
623
624 let haystack = self.matcher.haystack();
625 match self.matcher.next_match() {
626 // SAFETY: `Searcher` guarantees that `b` lies on unicode boundary,
627 // and self.start is either the start of the original string,
628 // or `b` was assigned to it, so it also lies on unicode boundary.
629 Some((_, b)) => unsafe {
630 let elt = haystack.get_unchecked(self.start..b);
631 self.start = b;
632 Some(elt)
633 },
634 None => self.get_end(),
635 }
636 }
637
638 #[inline]
639 fn next_back(&mut self) -> Option<&'a str>
640 where
641 P::Searcher: ReverseSearcher<'a>,
642 {
643 if self.finished {
644 return None;
645 }
646
647 if !self.allow_trailing_empty {
648 self.allow_trailing_empty = true;
649 match self.next_back() {
650 Some(elt) if !elt.is_empty() => return Some(elt),
651 _ => {
652 if self.finished {
653 return None;
654 }
655 }
656 }
657 }
658
659 let haystack = self.matcher.haystack();
660 match self.matcher.next_match_back() {
661 // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries.
662 Some((a, b)) => unsafe {
663 let elt = haystack.get_unchecked(b..self.end);
664 self.end = a;
665 Some(elt)
666 },
667 // SAFETY: `self.start` and `self.end` always lie on unicode boundaries.
668 None => unsafe {
669 self.finished = true;
670 Some(haystack.get_unchecked(self.start..self.end))
671 },
672 }
673 }
674
675 #[inline]
676 fn next_back_inclusive(&mut self) -> Option<&'a str>
677 where
678 P::Searcher: ReverseSearcher<'a>,
679 {
680 if self.finished {
681 return None;
682 }
683
684 if !self.allow_trailing_empty {
685 self.allow_trailing_empty = true;
686 match self.next_back_inclusive() {
687 Some(elt) if !elt.is_empty() => return Some(elt),
688 _ => {
689 if self.finished {
690 return None;
691 }
692 }
693 }
694 }
695
696 let haystack = self.matcher.haystack();
697 match self.matcher.next_match_back() {
698 // SAFETY: `Searcher` guarantees that `b` lies on unicode boundary,
699 // and self.end is either the end of the original string,
700 // or `b` was assigned to it, so it also lies on unicode boundary.
701 Some((_, b)) => unsafe {
702 let elt = haystack.get_unchecked(b..self.end);
703 self.end = b;
704 Some(elt)
705 },
706 // SAFETY: self.start is either the start of the original string,
707 // or start of a substring that represents the part of the string that hasn't
708 // iterated yet. Either way, it is guaranteed to lie on unicode boundary.
709 // self.end is either the end of the original string,
710 // or `b` was assigned to it, so it also lies on unicode boundary.
711 None => unsafe {
712 self.finished = true;
713 Some(haystack.get_unchecked(self.start..self.end))
714 },
715 }
716 }
717
718 #[inline]
719 fn as_str(&self) -> &'a str {
720 // `Self::get_end` doesn't change `self.start`
721 if self.finished {
722 return "";
723 }
724
725 // SAFETY: `self.start` and `self.end` always lie on unicode boundaries.
726 unsafe { self.matcher.haystack().get_unchecked(self.start..self.end) }
727 }
728 }
729
730 generate_pattern_iterators! {
731 forward:
732 /// Created with the method [`split`].
733 ///
734 /// [`split`]: str::split
735 struct Split;
736 reverse:
737 /// Created with the method [`rsplit`].
738 ///
739 /// [`rsplit`]: str::rsplit
740 struct RSplit;
741 stability:
742 #[stable(feature = "rust1", since = "1.0.0")]
743 internal:
744 SplitInternal yielding (&'a str);
745 delegate double ended;
746 }
747
748 impl<'a, P: Pattern<'a>> Split<'a, P> {
749 /// Returns remainder of the splitted string
750 ///
751 /// # Examples
752 ///
753 /// ```
754 /// #![feature(str_split_as_str)]
755 /// let mut split = "Mary had a little lamb".split(' ');
756 /// assert_eq!(split.as_str(), "Mary had a little lamb");
757 /// split.next();
758 /// assert_eq!(split.as_str(), "had a little lamb");
759 /// split.by_ref().for_each(drop);
760 /// assert_eq!(split.as_str(), "");
761 /// ```
762 #[inline]
763 #[unstable(feature = "str_split_as_str", issue = "77998")]
764 pub fn as_str(&self) -> &'a str {
765 self.0.as_str()
766 }
767 }
768
769 impl<'a, P: Pattern<'a>> RSplit<'a, P> {
770 /// Returns remainder of the splitted string
771 ///
772 /// # Examples
773 ///
774 /// ```
775 /// #![feature(str_split_as_str)]
776 /// let mut split = "Mary had a little lamb".rsplit(' ');
777 /// assert_eq!(split.as_str(), "Mary had a little lamb");
778 /// split.next();
779 /// assert_eq!(split.as_str(), "Mary had a little");
780 /// split.by_ref().for_each(drop);
781 /// assert_eq!(split.as_str(), "");
782 /// ```
783 #[inline]
784 #[unstable(feature = "str_split_as_str", issue = "77998")]
785 pub fn as_str(&self) -> &'a str {
786 self.0.as_str()
787 }
788 }
789
790 generate_pattern_iterators! {
791 forward:
792 /// Created with the method [`split_terminator`].
793 ///
794 /// [`split_terminator`]: str::split_terminator
795 struct SplitTerminator;
796 reverse:
797 /// Created with the method [`rsplit_terminator`].
798 ///
799 /// [`rsplit_terminator`]: str::rsplit_terminator
800 struct RSplitTerminator;
801 stability:
802 #[stable(feature = "rust1", since = "1.0.0")]
803 internal:
804 SplitInternal yielding (&'a str);
805 delegate double ended;
806 }
807
808 impl<'a, P: Pattern<'a>> SplitTerminator<'a, P> {
809 /// Returns remainder of the splitted string
810 ///
811 /// # Examples
812 ///
813 /// ```
814 /// #![feature(str_split_as_str)]
815 /// let mut split = "A..B..".split_terminator('.');
816 /// assert_eq!(split.as_str(), "A..B..");
817 /// split.next();
818 /// assert_eq!(split.as_str(), ".B..");
819 /// split.by_ref().for_each(drop);
820 /// assert_eq!(split.as_str(), "");
821 /// ```
822 #[inline]
823 #[unstable(feature = "str_split_as_str", issue = "77998")]
824 pub fn as_str(&self) -> &'a str {
825 self.0.as_str()
826 }
827 }
828
829 impl<'a, P: Pattern<'a>> RSplitTerminator<'a, P> {
830 /// Returns remainder of the splitted string
831 ///
832 /// # Examples
833 ///
834 /// ```
835 /// #![feature(str_split_as_str)]
836 /// let mut split = "A..B..".rsplit_terminator('.');
837 /// assert_eq!(split.as_str(), "A..B..");
838 /// split.next();
839 /// assert_eq!(split.as_str(), "A..B");
840 /// split.by_ref().for_each(drop);
841 /// assert_eq!(split.as_str(), "");
842 /// ```
843 #[inline]
844 #[unstable(feature = "str_split_as_str", issue = "77998")]
845 pub fn as_str(&self) -> &'a str {
846 self.0.as_str()
847 }
848 }
849
850 derive_pattern_clone! {
851 clone SplitNInternal
852 with |s| SplitNInternal { iter: s.iter.clone(), ..*s }
853 }
854
855 pub(super) struct SplitNInternal<'a, P: Pattern<'a>> {
856 pub(super) iter: SplitInternal<'a, P>,
857 /// The number of splits remaining
858 pub(super) count: usize,
859 }
860
861 impl<'a, P> fmt::Debug for SplitNInternal<'a, P>
862 where
863 P: Pattern<'a, Searcher: fmt::Debug>,
864 {
865 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
866 f.debug_struct("SplitNInternal")
867 .field("iter", &self.iter)
868 .field("count", &self.count)
869 .finish()
870 }
871 }
872
873 impl<'a, P: Pattern<'a>> SplitNInternal<'a, P> {
874 #[inline]
875 fn next(&mut self) -> Option<&'a str> {
876 match self.count {
877 0 => None,
878 1 => {
879 self.count = 0;
880 self.iter.get_end()
881 }
882 _ => {
883 self.count -= 1;
884 self.iter.next()
885 }
886 }
887 }
888
889 #[inline]
890 fn next_back(&mut self) -> Option<&'a str>
891 where
892 P::Searcher: ReverseSearcher<'a>,
893 {
894 match self.count {
895 0 => None,
896 1 => {
897 self.count = 0;
898 self.iter.get_end()
899 }
900 _ => {
901 self.count -= 1;
902 self.iter.next_back()
903 }
904 }
905 }
906
907 #[inline]
908 fn as_str(&self) -> &'a str {
909 self.iter.as_str()
910 }
911 }
912
913 generate_pattern_iterators! {
914 forward:
915 /// Created with the method [`splitn`].
916 ///
917 /// [`splitn`]: str::splitn
918 struct SplitN;
919 reverse:
920 /// Created with the method [`rsplitn`].
921 ///
922 /// [`rsplitn`]: str::rsplitn
923 struct RSplitN;
924 stability:
925 #[stable(feature = "rust1", since = "1.0.0")]
926 internal:
927 SplitNInternal yielding (&'a str);
928 delegate single ended;
929 }
930
931 impl<'a, P: Pattern<'a>> SplitN<'a, P> {
932 /// Returns remainder of the splitted string
933 ///
934 /// # Examples
935 ///
936 /// ```
937 /// #![feature(str_split_as_str)]
938 /// let mut split = "Mary had a little lamb".splitn(3, ' ');
939 /// assert_eq!(split.as_str(), "Mary had a little lamb");
940 /// split.next();
941 /// assert_eq!(split.as_str(), "had a little lamb");
942 /// split.by_ref().for_each(drop);
943 /// assert_eq!(split.as_str(), "");
944 /// ```
945 #[inline]
946 #[unstable(feature = "str_split_as_str", issue = "77998")]
947 pub fn as_str(&self) -> &'a str {
948 self.0.as_str()
949 }
950 }
951
952 impl<'a, P: Pattern<'a>> RSplitN<'a, P> {
953 /// Returns remainder of the splitted string
954 ///
955 /// # Examples
956 ///
957 /// ```
958 /// #![feature(str_split_as_str)]
959 /// let mut split = "Mary had a little lamb".rsplitn(3, ' ');
960 /// assert_eq!(split.as_str(), "Mary had a little lamb");
961 /// split.next();
962 /// assert_eq!(split.as_str(), "Mary had a little");
963 /// split.by_ref().for_each(drop);
964 /// assert_eq!(split.as_str(), "");
965 /// ```
966 #[inline]
967 #[unstable(feature = "str_split_as_str", issue = "77998")]
968 pub fn as_str(&self) -> &'a str {
969 self.0.as_str()
970 }
971 }
972
973 derive_pattern_clone! {
974 clone MatchIndicesInternal
975 with |s| MatchIndicesInternal(s.0.clone())
976 }
977
978 pub(super) struct MatchIndicesInternal<'a, P: Pattern<'a>>(pub(super) P::Searcher);
979
980 impl<'a, P> fmt::Debug for MatchIndicesInternal<'a, P>
981 where
982 P: Pattern<'a, Searcher: fmt::Debug>,
983 {
984 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
985 f.debug_tuple("MatchIndicesInternal").field(&self.0).finish()
986 }
987 }
988
989 impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> {
990 #[inline]
991 fn next(&mut self) -> Option<(usize, &'a str)> {
992 self.0
993 .next_match()
994 // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
995 .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) })
996 }
997
998 #[inline]
999 fn next_back(&mut self) -> Option<(usize, &'a str)>
1000 where
1001 P::Searcher: ReverseSearcher<'a>,
1002 {
1003 self.0
1004 .next_match_back()
1005 // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
1006 .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) })
1007 }
1008 }
1009
1010 generate_pattern_iterators! {
1011 forward:
1012 /// Created with the method [`match_indices`].
1013 ///
1014 /// [`match_indices`]: str::match_indices
1015 struct MatchIndices;
1016 reverse:
1017 /// Created with the method [`rmatch_indices`].
1018 ///
1019 /// [`rmatch_indices`]: str::rmatch_indices
1020 struct RMatchIndices;
1021 stability:
1022 #[stable(feature = "str_match_indices", since = "1.5.0")]
1023 internal:
1024 MatchIndicesInternal yielding ((usize, &'a str));
1025 delegate double ended;
1026 }
1027
1028 derive_pattern_clone! {
1029 clone MatchesInternal
1030 with |s| MatchesInternal(s.0.clone())
1031 }
1032
1033 pub(super) struct MatchesInternal<'a, P: Pattern<'a>>(pub(super) P::Searcher);
1034
1035 impl<'a, P> fmt::Debug for MatchesInternal<'a, P>
1036 where
1037 P: Pattern<'a, Searcher: fmt::Debug>,
1038 {
1039 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1040 f.debug_tuple("MatchesInternal").field(&self.0).finish()
1041 }
1042 }
1043
1044 impl<'a, P: Pattern<'a>> MatchesInternal<'a, P> {
1045 #[inline]
1046 fn next(&mut self) -> Option<&'a str> {
1047 // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
1048 self.0.next_match().map(|(a, b)| unsafe {
1049 // Indices are known to be on utf8 boundaries
1050 self.0.haystack().get_unchecked(a..b)
1051 })
1052 }
1053
1054 #[inline]
1055 fn next_back(&mut self) -> Option<&'a str>
1056 where
1057 P::Searcher: ReverseSearcher<'a>,
1058 {
1059 // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
1060 self.0.next_match_back().map(|(a, b)| unsafe {
1061 // Indices are known to be on utf8 boundaries
1062 self.0.haystack().get_unchecked(a..b)
1063 })
1064 }
1065 }
1066
1067 generate_pattern_iterators! {
1068 forward:
1069 /// Created with the method [`matches`].
1070 ///
1071 /// [`matches`]: str::matches
1072 struct Matches;
1073 reverse:
1074 /// Created with the method [`rmatches`].
1075 ///
1076 /// [`rmatches`]: str::rmatches
1077 struct RMatches;
1078 stability:
1079 #[stable(feature = "str_matches", since = "1.2.0")]
1080 internal:
1081 MatchesInternal yielding (&'a str);
1082 delegate double ended;
1083 }
1084
1085 /// An iterator over the lines of a string, as string slices.
1086 ///
1087 /// This struct is created with the [`lines`] method on [`str`].
1088 /// See its documentation for more.
1089 ///
1090 /// [`lines`]: str::lines
1091 #[stable(feature = "rust1", since = "1.0.0")]
1092 #[derive(Clone, Debug)]
1093 pub struct Lines<'a>(pub(super) Map<SplitTerminator<'a, char>, LinesAnyMap>);
1094
1095 #[stable(feature = "rust1", since = "1.0.0")]
1096 impl<'a> Iterator for Lines<'a> {
1097 type Item = &'a str;
1098
1099 #[inline]
1100 fn next(&mut self) -> Option<&'a str> {
1101 self.0.next()
1102 }
1103
1104 #[inline]
1105 fn size_hint(&self) -> (usize, Option<usize>) {
1106 self.0.size_hint()
1107 }
1108
1109 #[inline]
1110 fn last(mut self) -> Option<&'a str> {
1111 self.next_back()
1112 }
1113 }
1114
1115 #[stable(feature = "rust1", since = "1.0.0")]
1116 impl<'a> DoubleEndedIterator for Lines<'a> {
1117 #[inline]
1118 fn next_back(&mut self) -> Option<&'a str> {
1119 self.0.next_back()
1120 }
1121 }
1122
1123 #[stable(feature = "fused", since = "1.26.0")]
1124 impl FusedIterator for Lines<'_> {}
1125
1126 /// Created with the method [`lines_any`].
1127 ///
1128 /// [`lines_any`]: str::lines_any
1129 #[stable(feature = "rust1", since = "1.0.0")]
1130 #[rustc_deprecated(since = "1.4.0", reason = "use lines()/Lines instead now")]
1131 #[derive(Clone, Debug)]
1132 #[allow(deprecated)]
1133 pub struct LinesAny<'a>(pub(super) Lines<'a>);
1134
1135 #[stable(feature = "rust1", since = "1.0.0")]
1136 #[allow(deprecated)]
1137 impl<'a> Iterator for LinesAny<'a> {
1138 type Item = &'a str;
1139
1140 #[inline]
1141 fn next(&mut self) -> Option<&'a str> {
1142 self.0.next()
1143 }
1144
1145 #[inline]
1146 fn size_hint(&self) -> (usize, Option<usize>) {
1147 self.0.size_hint()
1148 }
1149 }
1150
1151 #[stable(feature = "rust1", since = "1.0.0")]
1152 #[allow(deprecated)]
1153 impl<'a> DoubleEndedIterator for LinesAny<'a> {
1154 #[inline]
1155 fn next_back(&mut self) -> Option<&'a str> {
1156 self.0.next_back()
1157 }
1158 }
1159
1160 #[stable(feature = "fused", since = "1.26.0")]
1161 #[allow(deprecated)]
1162 impl FusedIterator for LinesAny<'_> {}
1163
1164 /// An iterator over the non-whitespace substrings of a string,
1165 /// separated by any amount of whitespace.
1166 ///
1167 /// This struct is created by the [`split_whitespace`] method on [`str`].
1168 /// See its documentation for more.
1169 ///
1170 /// [`split_whitespace`]: str::split_whitespace
1171 #[stable(feature = "split_whitespace", since = "1.1.0")]
1172 #[derive(Clone, Debug)]
1173 pub struct SplitWhitespace<'a> {
1174 pub(super) inner: Filter<Split<'a, IsWhitespace>, IsNotEmpty>,
1175 }
1176
1177 /// An iterator over the non-ASCII-whitespace substrings of a string,
1178 /// separated by any amount of ASCII whitespace.
1179 ///
1180 /// This struct is created by the [`split_ascii_whitespace`] method on [`str`].
1181 /// See its documentation for more.
1182 ///
1183 /// [`split_ascii_whitespace`]: str::split_ascii_whitespace
1184 #[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1185 #[derive(Clone, Debug)]
1186 pub struct SplitAsciiWhitespace<'a> {
1187 pub(super) inner:
1188 Map<Filter<SliceSplit<'a, u8, IsAsciiWhitespace>, BytesIsNotEmpty>, UnsafeBytesToStr>,
1189 }
1190
1191 /// An iterator over the substrings of a string,
1192 /// terminated by a substring matching to a predicate function
1193 /// Unlike `Split`, it contains the matched part as a terminator
1194 /// of the subslice.
1195 ///
1196 /// This struct is created by the [`split_inclusive`] method on [`str`].
1197 /// See its documentation for more.
1198 ///
1199 /// [`split_inclusive`]: str::split_inclusive
1200 #[stable(feature = "split_inclusive", since = "1.51.0")]
1201 pub struct SplitInclusive<'a, P: Pattern<'a>>(pub(super) SplitInternal<'a, P>);
1202
1203 #[stable(feature = "split_whitespace", since = "1.1.0")]
1204 impl<'a> Iterator for SplitWhitespace<'a> {
1205 type Item = &'a str;
1206
1207 #[inline]
1208 fn next(&mut self) -> Option<&'a str> {
1209 self.inner.next()
1210 }
1211
1212 #[inline]
1213 fn size_hint(&self) -> (usize, Option<usize>) {
1214 self.inner.size_hint()
1215 }
1216
1217 #[inline]
1218 fn last(mut self) -> Option<&'a str> {
1219 self.next_back()
1220 }
1221 }
1222
1223 #[stable(feature = "split_whitespace", since = "1.1.0")]
1224 impl<'a> DoubleEndedIterator for SplitWhitespace<'a> {
1225 #[inline]
1226 fn next_back(&mut self) -> Option<&'a str> {
1227 self.inner.next_back()
1228 }
1229 }
1230
1231 #[stable(feature = "fused", since = "1.26.0")]
1232 impl FusedIterator for SplitWhitespace<'_> {}
1233
1234 impl<'a> SplitWhitespace<'a> {
1235 /// Returns remainder of the splitted string
1236 ///
1237 /// # Examples
1238 ///
1239 /// ```
1240 /// #![feature(str_split_whitespace_as_str)]
1241 ///
1242 /// let mut split = "Mary had a little lamb".split_whitespace();
1243 /// assert_eq!(split.as_str(), "Mary had a little lamb");
1244 ///
1245 /// split.next();
1246 /// assert_eq!(split.as_str(), "had a little lamb");
1247 ///
1248 /// split.by_ref().for_each(drop);
1249 /// assert_eq!(split.as_str(), "");
1250 /// ```
1251 #[inline]
1252 #[must_use]
1253 #[unstable(feature = "str_split_whitespace_as_str", issue = "77998")]
1254 pub fn as_str(&self) -> &'a str {
1255 self.inner.iter.as_str()
1256 }
1257 }
1258
1259 #[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1260 impl<'a> Iterator for SplitAsciiWhitespace<'a> {
1261 type Item = &'a str;
1262
1263 #[inline]
1264 fn next(&mut self) -> Option<&'a str> {
1265 self.inner.next()
1266 }
1267
1268 #[inline]
1269 fn size_hint(&self) -> (usize, Option<usize>) {
1270 self.inner.size_hint()
1271 }
1272
1273 #[inline]
1274 fn last(mut self) -> Option<&'a str> {
1275 self.next_back()
1276 }
1277 }
1278
1279 #[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1280 impl<'a> DoubleEndedIterator for SplitAsciiWhitespace<'a> {
1281 #[inline]
1282 fn next_back(&mut self) -> Option<&'a str> {
1283 self.inner.next_back()
1284 }
1285 }
1286
1287 #[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1288 impl FusedIterator for SplitAsciiWhitespace<'_> {}
1289
1290 impl<'a> SplitAsciiWhitespace<'a> {
1291 /// Returns remainder of the splitted string
1292 ///
1293 /// # Examples
1294 ///
1295 /// ```
1296 /// #![feature(str_split_whitespace_as_str)]
1297 ///
1298 /// let mut split = "Mary had a little lamb".split_ascii_whitespace();
1299 /// assert_eq!(split.as_str(), "Mary had a little lamb");
1300 ///
1301 /// split.next();
1302 /// assert_eq!(split.as_str(), "had a little lamb");
1303 ///
1304 /// split.by_ref().for_each(drop);
1305 /// assert_eq!(split.as_str(), "");
1306 /// ```
1307 #[inline]
1308 #[must_use]
1309 #[unstable(feature = "str_split_whitespace_as_str", issue = "77998")]
1310 pub fn as_str(&self) -> &'a str {
1311 if self.inner.iter.iter.finished {
1312 return "";
1313 }
1314
1315 // SAFETY: Slice is created from str.
1316 unsafe { crate::str::from_utf8_unchecked(&self.inner.iter.iter.v) }
1317 }
1318 }
1319
1320 #[stable(feature = "split_inclusive", since = "1.51.0")]
1321 impl<'a, P: Pattern<'a>> Iterator for SplitInclusive<'a, P> {
1322 type Item = &'a str;
1323
1324 #[inline]
1325 fn next(&mut self) -> Option<&'a str> {
1326 self.0.next_inclusive()
1327 }
1328 }
1329
1330 #[stable(feature = "split_inclusive", since = "1.51.0")]
1331 impl<'a, P: Pattern<'a, Searcher: fmt::Debug>> fmt::Debug for SplitInclusive<'a, P> {
1332 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1333 f.debug_struct("SplitInclusive").field("0", &self.0).finish()
1334 }
1335 }
1336
1337 // FIXME(#26925) Remove in favor of `#[derive(Clone)]`
1338 #[stable(feature = "split_inclusive", since = "1.51.0")]
1339 impl<'a, P: Pattern<'a, Searcher: Clone>> Clone for SplitInclusive<'a, P> {
1340 fn clone(&self) -> Self {
1341 SplitInclusive(self.0.clone())
1342 }
1343 }
1344
1345 #[stable(feature = "split_inclusive", since = "1.51.0")]
1346 impl<'a, P: Pattern<'a, Searcher: ReverseSearcher<'a>>> DoubleEndedIterator
1347 for SplitInclusive<'a, P>
1348 {
1349 #[inline]
1350 fn next_back(&mut self) -> Option<&'a str> {
1351 self.0.next_back_inclusive()
1352 }
1353 }
1354
1355 #[stable(feature = "split_inclusive", since = "1.51.0")]
1356 impl<'a, P: Pattern<'a>> FusedIterator for SplitInclusive<'a, P> {}
1357
1358 impl<'a, P: Pattern<'a>> SplitInclusive<'a, P> {
1359 /// Returns remainder of the splitted string
1360 ///
1361 /// # Examples
1362 ///
1363 /// ```
1364 /// #![feature(str_split_inclusive_as_str)]
1365 /// let mut split = "Mary had a little lamb".split_inclusive(' ');
1366 /// assert_eq!(split.as_str(), "Mary had a little lamb");
1367 /// split.next();
1368 /// assert_eq!(split.as_str(), "had a little lamb");
1369 /// split.by_ref().for_each(drop);
1370 /// assert_eq!(split.as_str(), "");
1371 /// ```
1372 #[inline]
1373 #[unstable(feature = "str_split_inclusive_as_str", issue = "77998")]
1374 pub fn as_str(&self) -> &'a str {
1375 self.0.as_str()
1376 }
1377 }
1378
1379 /// An iterator of [`u16`] over the string encoded as UTF-16.
1380 ///
1381 /// This struct is created by the [`encode_utf16`] method on [`str`].
1382 /// See its documentation for more.
1383 ///
1384 /// [`encode_utf16`]: str::encode_utf16
1385 #[derive(Clone)]
1386 #[stable(feature = "encode_utf16", since = "1.8.0")]
1387 pub struct EncodeUtf16<'a> {
1388 pub(super) chars: Chars<'a>,
1389 pub(super) extra: u16,
1390 }
1391
1392 #[stable(feature = "collection_debug", since = "1.17.0")]
1393 impl fmt::Debug for EncodeUtf16<'_> {
1394 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1395 f.debug_struct("EncodeUtf16").finish_non_exhaustive()
1396 }
1397 }
1398
1399 #[stable(feature = "encode_utf16", since = "1.8.0")]
1400 impl<'a> Iterator for EncodeUtf16<'a> {
1401 type Item = u16;
1402
1403 #[inline]
1404 fn next(&mut self) -> Option<u16> {
1405 if self.extra != 0 {
1406 let tmp = self.extra;
1407 self.extra = 0;
1408 return Some(tmp);
1409 }
1410
1411 let mut buf = [0; 2];
1412 self.chars.next().map(|ch| {
1413 let n = ch.encode_utf16(&mut buf).len();
1414 if n == 2 {
1415 self.extra = buf[1];
1416 }
1417 buf[0]
1418 })
1419 }
1420
1421 #[inline]
1422 fn size_hint(&self) -> (usize, Option<usize>) {
1423 let (low, high) = self.chars.size_hint();
1424 // every char gets either one u16 or two u16,
1425 // so this iterator is between 1 or 2 times as
1426 // long as the underlying iterator.
1427 (low, high.and_then(|n| n.checked_mul(2)))
1428 }
1429 }
1430
1431 #[stable(feature = "fused", since = "1.26.0")]
1432 impl FusedIterator for EncodeUtf16<'_> {}
1433
1434 /// The return type of [`str::escape_debug`].
1435 #[stable(feature = "str_escape", since = "1.34.0")]
1436 #[derive(Clone, Debug)]
1437 pub struct EscapeDebug<'a> {
1438 pub(super) inner: Chain<
1439 Flatten<option::IntoIter<char::EscapeDebug>>,
1440 FlatMap<Chars<'a>, char::EscapeDebug, CharEscapeDebugContinue>,
1441 >,
1442 }
1443
1444 /// The return type of [`str::escape_default`].
1445 #[stable(feature = "str_escape", since = "1.34.0")]
1446 #[derive(Clone, Debug)]
1447 pub struct EscapeDefault<'a> {
1448 pub(super) inner: FlatMap<Chars<'a>, char::EscapeDefault, CharEscapeDefault>,
1449 }
1450
1451 /// The return type of [`str::escape_unicode`].
1452 #[stable(feature = "str_escape", since = "1.34.0")]
1453 #[derive(Clone, Debug)]
1454 pub struct EscapeUnicode<'a> {
1455 pub(super) inner: FlatMap<Chars<'a>, char::EscapeUnicode, CharEscapeUnicode>,
1456 }
1457
1458 macro_rules! escape_types_impls {
1459 ($( $Name: ident ),+) => {$(
1460 #[stable(feature = "str_escape", since = "1.34.0")]
1461 impl<'a> fmt::Display for $Name<'a> {
1462 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1463 self.clone().try_for_each(|c| f.write_char(c))
1464 }
1465 }
1466
1467 #[stable(feature = "str_escape", since = "1.34.0")]
1468 impl<'a> Iterator for $Name<'a> {
1469 type Item = char;
1470
1471 #[inline]
1472 fn next(&mut self) -> Option<char> { self.inner.next() }
1473
1474 #[inline]
1475 fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
1476
1477 #[inline]
1478 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
1479 Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Output = Acc>
1480 {
1481 self.inner.try_fold(init, fold)
1482 }
1483
1484 #[inline]
1485 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
1486 where Fold: FnMut(Acc, Self::Item) -> Acc,
1487 {
1488 self.inner.fold(init, fold)
1489 }
1490 }
1491
1492 #[stable(feature = "str_escape", since = "1.34.0")]
1493 impl<'a> FusedIterator for $Name<'a> {}
1494 )+}
1495 }
1496
1497 escape_types_impls!(EscapeDebug, EscapeDefault, EscapeUnicode);