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