1 //! Iterators for `str` methods.
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}
;
10 use crate::slice
::{self, Split as SliceSplit}
;
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}
;
21 /// An iterator over the [`char`]s of a string slice.
24 /// This struct is created by the [`chars`] method on [`str`].
25 /// See its documentation for more.
27 /// [`char`]: prim@char
28 /// [`chars`]: str::chars
30 #[stable(feature = "rust1", since = "1.0.0")]
31 pub struct Chars
<'a
> {
32 pub(super) iter
: slice
::Iter
<'a
, u8>,
35 #[stable(feature = "rust1", since = "1.0.0")]
36 impl<'a
> Iterator
for Chars
<'a
> {
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) }
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()
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
))
63 fn last(mut self) -> Option
<char> {
64 // No need to go through the entire string.
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
{
73 f
.debug_list().entries(self.clone()).finish()?
;
79 #[stable(feature = "rust1", since = "1.0.0")]
80 impl<'a
> DoubleEndedIterator
for Chars
<'a
> {
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) }
90 #[stable(feature = "fused", since = "1.26.0")]
91 impl FusedIterator
for Chars
<'_
> {}
94 /// Views the underlying data as a subslice of the original data.
96 /// This has the same lifetime as the original slice, and so the
97 /// iterator can continue to be used while this exists.
102 /// let mut chars = "abc".chars();
104 /// assert_eq!(chars.as_str(), "abc");
106 /// assert_eq!(chars.as_str(), "bc");
109 /// assert_eq!(chars.as_str(), "");
111 #[stable(feature = "iter_to_slice", since = "1.4.0")]
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()) }
120 /// An iterator over the [`char`]s of a string slice, and their positions.
122 /// This struct is created by the [`char_indices`] method on [`str`].
123 /// See its documentation for more.
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
>,
134 #[stable(feature = "rust1", since = "1.0.0")]
135 impl<'a
> Iterator
for CharIndices
<'a
> {
136 type Item
= (usize, char);
139 fn next(&mut self) -> Option
<(usize, char)> {
140 let pre_len
= self.iter
.iter
.len();
141 match self.iter
.next() {
144 let index
= self.front_offset
;
145 let len
= self.iter
.iter
.len();
146 self.front_offset
+= pre_len
- len
;
153 fn count(self) -> usize {
158 fn size_hint(&self) -> (usize, Option
<usize>) {
159 self.iter
.size_hint()
163 fn last(mut self) -> Option
<(usize, char)> {
164 // No need to go through the entire string.
169 #[stable(feature = "rust1", since = "1.0.0")]
170 impl<'a
> DoubleEndedIterator
for CharIndices
<'a
> {
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();
180 #[stable(feature = "fused", since = "1.26.0")]
181 impl FusedIterator
for CharIndices
<'_
> {}
183 impl<'a
> CharIndices
<'a
> {
184 /// Views the underlying data as a subslice of the original data.
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")]
191 pub fn as_str(&self) -> &'a
str {
195 /// Returns the byte position of the next character, or the length
196 /// of the underlying string if there are no more characters.
201 /// #![feature(char_indices_offset)]
202 /// let mut chars = "a楽".char_indices();
204 /// assert_eq!(chars.offset(), 0);
205 /// assert_eq!(chars.next(), Some((0, 'a')));
207 /// assert_eq!(chars.offset(), 1);
208 /// assert_eq!(chars.next(), Some((1, '楽')));
210 /// assert_eq!(chars.offset(), 4);
211 /// assert_eq!(chars.next(), None);
214 #[unstable(feature = "char_indices_offset", issue = "83871")]
215 pub fn offset(&self) -> usize {
220 /// An iterator over the bytes of a string slice.
222 /// This struct is created by the [`bytes`] method on [`str`].
223 /// See its documentation for more.
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>>);
230 #[stable(feature = "rust1", since = "1.0.0")]
231 impl Iterator
for Bytes
<'_
> {
235 fn next(&mut self) -> Option
<u8> {
240 fn size_hint(&self) -> (usize, Option
<usize>) {
245 fn count(self) -> usize {
250 fn last(self) -> Option
<Self::Item
> {
255 fn nth(&mut self, n
: usize) -> Option
<Self::Item
> {
260 fn all
<F
>(&mut self, f
: F
) -> bool
262 F
: FnMut(Self::Item
) -> bool
,
268 fn any
<F
>(&mut self, f
: F
) -> bool
270 F
: FnMut(Self::Item
) -> bool
,
276 fn find
<P
>(&mut self, predicate
: P
) -> Option
<Self::Item
>
278 P
: FnMut(&Self::Item
) -> bool
,
280 self.0.find
(predicate
)
284 fn position
<P
>(&mut self, predicate
: P
) -> Option
<usize>
286 P
: FnMut(Self::Item
) -> bool
,
288 self.0.position(predicate
)
292 fn rposition
<P
>(&mut self, predicate
: P
) -> Option
<usize>
294 P
: FnMut(Self::Item
) -> bool
,
296 self.0.rposition(predicate
)
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) }
308 #[stable(feature = "rust1", since = "1.0.0")]
309 impl DoubleEndedIterator
for Bytes
<'_
> {
311 fn next_back(&mut self) -> Option
<u8> {
316 fn nth_back(&mut self, n
: usize) -> Option
<Self::Item
> {
321 fn rfind
<P
>(&mut self, predicate
: P
) -> Option
<Self::Item
>
323 P
: FnMut(&Self::Item
) -> bool
,
325 self.0.rfind(predicate
)
329 #[stable(feature = "rust1", since = "1.0.0")]
330 impl ExactSizeIterator
for Bytes
<'_
> {
332 fn len(&self) -> usize {
337 fn is_empty(&self) -> bool
{
342 #[stable(feature = "fused", since = "1.26.0")]
343 impl FusedIterator
for Bytes
<'_
> {}
345 #[unstable(feature = "trusted_len", issue = "37572")]
346 unsafe impl TrustedLen
for Bytes
<'_
> {}
349 #[unstable(feature = "trusted_random_access", issue = "none")]
350 unsafe impl TrustedRandomAccess
for Bytes
<'_
> {}
353 #[unstable(feature = "trusted_random_access", issue = "none")]
354 unsafe impl TrustedRandomAccessNoCoerce
for Bytes
<'_
> {
355 const MAY_HAVE_SIDE_EFFECT
: bool
= false;
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
>
364 P
: Pattern
<'a
, Searcher
: Clone
>,
366 fn clone(&self) -> Self {
374 /// This macro generates two public iterator structs
375 /// wrapping a private internal one that makes use of the `Pattern` API.
377 /// For all patterns `P: Pattern<'a>` the following items will be
378 /// generated (generics omitted):
380 /// struct $forward_iterator($internal_iterator);
381 /// struct $reverse_iterator($internal_iterator);
383 /// impl Iterator for $forward_iterator
384 /// { /* internal ends up calling Searcher::next_match() */ }
386 /// impl DoubleEndedIterator for $forward_iterator
387 /// where P::Searcher: DoubleEndedSearcher
388 /// { /* internal ends up calling Searcher::next_match_back() */ }
390 /// impl Iterator for $reverse_iterator
391 /// where P::Searcher: ReverseSearcher
392 /// { /* internal ends up calling Searcher::next_match_back() */ }
394 /// impl DoubleEndedIterator for $reverse_iterator
395 /// where P::Searcher: DoubleEndedSearcher
396 /// { /* internal ends up calling Searcher::next_match() */ }
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.
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)
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
{
416 $
(#[$forward_iterator_attribute:meta])*
417 struct $forward_iterator
:ident
;
421 $
(#[$reverse_iterator_attribute:meta])*
422 struct $reverse_iterator
:ident
;
424 // Stability of all generated items
426 $
(#[$common_stability_attribute:meta])*
428 // Internal almost-iterator that is being delegated to
430 $internal_iterator
:ident
yielding ($iterty
:ty
);
432 // Kind of delegation - either single ended or double ended
435 $
(#[$forward_iterator_attribute])*
436 $
(#[$common_stability_attribute])*
437 pub struct $forward_iterator
<'a
, P
: Pattern
<'a
>>(pub(super) $internal_iterator
<'a
, P
>);
439 $
(#[$common_stability_attribute])*
440 impl<'a
, P
> fmt
::Debug
for $forward_iterator
<'a
, P
>
442 P
: Pattern
<'a
, Searcher
: fmt
::Debug
>,
444 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
445 f
.debug_tuple(stringify
!($forward_iterator
))
451 $
(#[$common_stability_attribute])*
452 impl<'a
, P
: Pattern
<'a
>> Iterator
for $forward_iterator
<'a
, P
> {
456 fn next(&mut self) -> Option
<$iterty
> {
461 $
(#[$common_stability_attribute])*
462 impl<'a
, P
> Clone
for $forward_iterator
<'a
, P
>
464 P
: Pattern
<'a
, Searcher
: Clone
>,
466 fn clone(&self) -> Self {
467 $
forward_iterator(self.0.clone())
471 $
(#[$reverse_iterator_attribute])*
472 $
(#[$common_stability_attribute])*
473 pub struct $reverse_iterator
<'a
, P
: Pattern
<'a
>>(pub(super) $internal_iterator
<'a
, P
>);
475 $
(#[$common_stability_attribute])*
476 impl<'a
, P
> fmt
::Debug
for $reverse_iterator
<'a
, P
>
478 P
: Pattern
<'a
, Searcher
: fmt
::Debug
>,
480 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
481 f
.debug_tuple(stringify
!($reverse_iterator
))
487 $
(#[$common_stability_attribute])*
488 impl<'a
, P
> Iterator
for $reverse_iterator
<'a
, P
>
490 P
: Pattern
<'a
, Searcher
: ReverseSearcher
<'a
>>,
495 fn next(&mut self) -> Option
<$iterty
> {
500 $
(#[$common_stability_attribute])*
501 impl<'a
, P
> Clone
for $reverse_iterator
<'a
, P
>
503 P
: Pattern
<'a
, Searcher
: Clone
>,
505 fn clone(&self) -> Self {
506 $
reverse_iterator(self.0.clone())
510 #[stable(feature = "fused", since = "1.26.0")]
511 impl<'a
, P
: Pattern
<'a
>> FusedIterator
for $forward_iterator
<'a
, P
> {}
513 #[stable(feature = "fused", since = "1.26.0")]
514 impl<'a
, P
> FusedIterator
for $reverse_iterator
<'a
, P
>
516 P
: Pattern
<'a
, Searcher
: ReverseSearcher
<'a
>>,
519 generate_pattern_iterators
!($
($t
)* with $
(#[$common_stability_attribute])*,
521 $reverse_iterator
, $iterty
);
524 double ended
; with $
(#[$common_stability_attribute:meta])*,
525 $forward_iterator
:ident
,
526 $reverse_iterator
:ident
, $iterty
:ty
528 $
(#[$common_stability_attribute])*
529 impl<'a
, P
> DoubleEndedIterator
for $forward_iterator
<'a
, P
>
531 P
: Pattern
<'a
, Searcher
: DoubleEndedSearcher
<'a
>>,
534 fn next_back(&mut self) -> Option
<$iterty
> {
539 $
(#[$common_stability_attribute])*
540 impl<'a
, P
> DoubleEndedIterator
for $reverse_iterator
<'a
, P
>
542 P
: Pattern
<'a
, Searcher
: DoubleEndedSearcher
<'a
>>,
545 fn next_back(&mut self) -> Option
<$iterty
> {
551 single ended
; with $
(#[$common_stability_attribute:meta])*,
552 $forward_iterator
:ident
,
553 $reverse_iterator
:ident
, $iterty
:ty
557 derive_pattern_clone
! {
559 with
|s
| SplitInternal { matcher: s.matcher.clone(), ..*s }
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
,
570 impl<'a
, P
> fmt
::Debug
for SplitInternal
<'a
, P
>
572 P
: Pattern
<'a
, Searcher
: fmt
::Debug
>,
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
)
585 impl<'a
, P
: Pattern
<'a
>> SplitInternal
<'a
, P
> {
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.
592 let string
= self.matcher
.haystack().get_unchecked(self.start
..self.end
);
601 fn next(&mut self) -> Option
<&'a
str> {
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
);
614 None
=> self.get_end(),
619 fn next_inclusive(&mut self) -> Option
<&'a
str> {
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
);
634 None
=> self.get_end(),
639 fn next_back(&mut self) -> Option
<&'a
str>
641 P
::Searcher
: ReverseSearcher
<'a
>,
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
),
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
);
667 // SAFETY: `self.start` and `self.end` always lie on unicode boundaries.
669 self.finished
= true;
670 Some(haystack
.get_unchecked(self.start
..self.end
))
676 fn next_back_inclusive(&mut self) -> Option
<&'a
str>
678 P
::Searcher
: ReverseSearcher
<'a
>,
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
),
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
);
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.
712 self.finished
= true;
713 Some(haystack
.get_unchecked(self.start
..self.end
))
719 fn as_str(&self) -> &'a
str {
720 // `Self::get_end` doesn't change `self.start`
725 // SAFETY: `self.start` and `self.end` always lie on unicode boundaries.
726 unsafe { self.matcher.haystack().get_unchecked(self.start..self.end) }
730 generate_pattern_iterators
! {
732 /// Created with the method [`split`].
734 /// [`split`]: str::split
737 /// Created with the method [`rsplit`].
739 /// [`rsplit`]: str::rsplit
742 #[stable(feature = "rust1", since = "1.0.0")]
744 SplitInternal
yielding (&'a
str);
745 delegate double ended
;
748 impl<'a
, P
: Pattern
<'a
>> Split
<'a
, P
> {
749 /// Returns remainder of the splitted string
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");
758 /// assert_eq!(split.as_str(), "had a little lamb");
759 /// split.by_ref().for_each(drop);
760 /// assert_eq!(split.as_str(), "");
763 #[unstable(feature = "str_split_as_str", issue = "77998")]
764 pub fn as_str(&self) -> &'a
str {
769 impl<'a
, P
: Pattern
<'a
>> RSplit
<'a
, P
> {
770 /// Returns remainder of the splitted string
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");
779 /// assert_eq!(split.as_str(), "Mary had a little");
780 /// split.by_ref().for_each(drop);
781 /// assert_eq!(split.as_str(), "");
784 #[unstable(feature = "str_split_as_str", issue = "77998")]
785 pub fn as_str(&self) -> &'a
str {
790 generate_pattern_iterators
! {
792 /// Created with the method [`split_terminator`].
794 /// [`split_terminator`]: str::split_terminator
795 struct SplitTerminator
;
797 /// Created with the method [`rsplit_terminator`].
799 /// [`rsplit_terminator`]: str::rsplit_terminator
800 struct RSplitTerminator
;
802 #[stable(feature = "rust1", since = "1.0.0")]
804 SplitInternal
yielding (&'a
str);
805 delegate double ended
;
808 impl<'a
, P
: Pattern
<'a
>> SplitTerminator
<'a
, P
> {
809 /// Returns remainder of the splitted string
814 /// #![feature(str_split_as_str)]
815 /// let mut split = "A..B..".split_terminator('.');
816 /// assert_eq!(split.as_str(), "A..B..");
818 /// assert_eq!(split.as_str(), ".B..");
819 /// split.by_ref().for_each(drop);
820 /// assert_eq!(split.as_str(), "");
823 #[unstable(feature = "str_split_as_str", issue = "77998")]
824 pub fn as_str(&self) -> &'a
str {
829 impl<'a
, P
: Pattern
<'a
>> RSplitTerminator
<'a
, P
> {
830 /// Returns remainder of the splitted string
835 /// #![feature(str_split_as_str)]
836 /// let mut split = "A..B..".rsplit_terminator('.');
837 /// assert_eq!(split.as_str(), "A..B..");
839 /// assert_eq!(split.as_str(), "A..B");
840 /// split.by_ref().for_each(drop);
841 /// assert_eq!(split.as_str(), "");
844 #[unstable(feature = "str_split_as_str", issue = "77998")]
845 pub fn as_str(&self) -> &'a
str {
850 derive_pattern_clone
! {
852 with
|s
| SplitNInternal { iter: s.iter.clone(), ..*s }
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,
861 impl<'a
, P
> fmt
::Debug
for SplitNInternal
<'a
, P
>
863 P
: Pattern
<'a
, Searcher
: fmt
::Debug
>,
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
)
873 impl<'a
, P
: Pattern
<'a
>> SplitNInternal
<'a
, P
> {
875 fn next(&mut self) -> Option
<&'a
str> {
890 fn next_back(&mut self) -> Option
<&'a
str>
892 P
::Searcher
: ReverseSearcher
<'a
>,
902 self.iter
.next_back()
908 fn as_str(&self) -> &'a
str {
913 generate_pattern_iterators
! {
915 /// Created with the method [`splitn`].
917 /// [`splitn`]: str::splitn
920 /// Created with the method [`rsplitn`].
922 /// [`rsplitn`]: str::rsplitn
925 #[stable(feature = "rust1", since = "1.0.0")]
927 SplitNInternal
yielding (&'a
str);
928 delegate single ended
;
931 impl<'a
, P
: Pattern
<'a
>> SplitN
<'a
, P
> {
932 /// Returns remainder of the splitted string
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");
941 /// assert_eq!(split.as_str(), "had a little lamb");
942 /// split.by_ref().for_each(drop);
943 /// assert_eq!(split.as_str(), "");
946 #[unstable(feature = "str_split_as_str", issue = "77998")]
947 pub fn as_str(&self) -> &'a
str {
952 impl<'a
, P
: Pattern
<'a
>> RSplitN
<'a
, P
> {
953 /// Returns remainder of the splitted string
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");
962 /// assert_eq!(split.as_str(), "Mary had a little");
963 /// split.by_ref().for_each(drop);
964 /// assert_eq!(split.as_str(), "");
967 #[unstable(feature = "str_split_as_str", issue = "77998")]
968 pub fn as_str(&self) -> &'a
str {
973 derive_pattern_clone
! {
974 clone MatchIndicesInternal
975 with
|s
| MatchIndicesInternal(s
.0.clone())
978 pub(super) struct MatchIndicesInternal
<'a
, P
: Pattern
<'a
>>(pub(super) P
::Searcher
);
980 impl<'a
, P
> fmt
::Debug
for MatchIndicesInternal
<'a
, P
>
982 P
: Pattern
<'a
, Searcher
: fmt
::Debug
>,
984 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
985 f
.debug_tuple("MatchIndicesInternal").field(&self.0).finish()
989 impl<'a
, P
: Pattern
<'a
>> MatchIndicesInternal
<'a
, P
> {
991 fn next(&mut self) -> Option
<(usize, &'a
str)> {
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)) }
)
999 fn next_back(&mut self) -> Option
<(usize, &'a
str)>
1001 P
::Searcher
: ReverseSearcher
<'a
>,
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)) }
)
1010 generate_pattern_iterators
! {
1012 /// Created with the method [`match_indices`].
1014 /// [`match_indices`]: str::match_indices
1015 struct MatchIndices
;
1017 /// Created with the method [`rmatch_indices`].
1019 /// [`rmatch_indices`]: str::rmatch_indices
1020 struct RMatchIndices
;
1022 #[stable(feature = "str_match_indices", since = "1.5.0")]
1024 MatchIndicesInternal
yielding ((usize, &'a
str));
1025 delegate double ended
;
1028 derive_pattern_clone
! {
1029 clone MatchesInternal
1030 with
|s
| MatchesInternal(s
.0.clone())
1033 pub(super) struct MatchesInternal
<'a
, P
: Pattern
<'a
>>(pub(super) P
::Searcher
);
1035 impl<'a
, P
> fmt
::Debug
for MatchesInternal
<'a
, P
>
1037 P
: Pattern
<'a
, Searcher
: fmt
::Debug
>,
1039 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
1040 f
.debug_tuple("MatchesInternal").field(&self.0).finish()
1044 impl<'a
, P
: Pattern
<'a
>> MatchesInternal
<'a
, P
> {
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
)
1055 fn next_back(&mut self) -> Option
<&'a
str>
1057 P
::Searcher
: ReverseSearcher
<'a
>,
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
)
1067 generate_pattern_iterators
! {
1069 /// Created with the method [`matches`].
1071 /// [`matches`]: str::matches
1074 /// Created with the method [`rmatches`].
1076 /// [`rmatches`]: str::rmatches
1079 #[stable(feature = "str_matches", since = "1.2.0")]
1081 MatchesInternal
yielding (&'a
str);
1082 delegate double ended
;
1085 /// An iterator over the lines of a string, as string slices.
1087 /// This struct is created with the [`lines`] method on [`str`].
1088 /// See its documentation for more.
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
>);
1095 #[stable(feature = "rust1", since = "1.0.0")]
1096 impl<'a
> Iterator
for Lines
<'a
> {
1097 type Item
= &'a
str;
1100 fn next(&mut self) -> Option
<&'a
str> {
1105 fn size_hint(&self) -> (usize, Option
<usize>) {
1110 fn last(mut self) -> Option
<&'a
str> {
1115 #[stable(feature = "rust1", since = "1.0.0")]
1116 impl<'a
> DoubleEndedIterator
for Lines
<'a
> {
1118 fn next_back(&mut self) -> Option
<&'a
str> {
1123 #[stable(feature = "fused", since = "1.26.0")]
1124 impl FusedIterator
for Lines
<'_
> {}
1126 /// Created with the method [`lines_any`].
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
>);
1135 #[stable(feature = "rust1", since = "1.0.0")]
1136 #[allow(deprecated)]
1137 impl<'a
> Iterator
for LinesAny
<'a
> {
1138 type Item
= &'a
str;
1141 fn next(&mut self) -> Option
<&'a
str> {
1146 fn size_hint(&self) -> (usize, Option
<usize>) {
1151 #[stable(feature = "rust1", since = "1.0.0")]
1152 #[allow(deprecated)]
1153 impl<'a
> DoubleEndedIterator
for LinesAny
<'a
> {
1155 fn next_back(&mut self) -> Option
<&'a
str> {
1160 #[stable(feature = "fused", since = "1.26.0")]
1161 #[allow(deprecated)]
1162 impl FusedIterator
for LinesAny
<'_
> {}
1164 /// An iterator over the non-whitespace substrings of a string,
1165 /// separated by any amount of whitespace.
1167 /// This struct is created by the [`split_whitespace`] method on [`str`].
1168 /// See its documentation for more.
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
>,
1177 /// An iterator over the non-ASCII-whitespace substrings of a string,
1178 /// separated by any amount of ASCII whitespace.
1180 /// This struct is created by the [`split_ascii_whitespace`] method on [`str`].
1181 /// See its documentation for more.
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
> {
1188 Map
<Filter
<SliceSplit
<'a
, u8, IsAsciiWhitespace
>, BytesIsNotEmpty
>, UnsafeBytesToStr
>,
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.
1196 /// This struct is created by the [`split_inclusive`] method on [`str`].
1197 /// See its documentation for more.
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
>);
1203 #[stable(feature = "split_whitespace", since = "1.1.0")]
1204 impl<'a
> Iterator
for SplitWhitespace
<'a
> {
1205 type Item
= &'a
str;
1208 fn next(&mut self) -> Option
<&'a
str> {
1213 fn size_hint(&self) -> (usize, Option
<usize>) {
1214 self.inner
.size_hint()
1218 fn last(mut self) -> Option
<&'a
str> {
1223 #[stable(feature = "split_whitespace", since = "1.1.0")]
1224 impl<'a
> DoubleEndedIterator
for SplitWhitespace
<'a
> {
1226 fn next_back(&mut self) -> Option
<&'a
str> {
1227 self.inner
.next_back()
1231 #[stable(feature = "fused", since = "1.26.0")]
1232 impl FusedIterator
for SplitWhitespace
<'_
> {}
1234 impl<'a
> SplitWhitespace
<'a
> {
1235 /// Returns remainder of the splitted string
1240 /// #![feature(str_split_whitespace_as_str)]
1242 /// let mut split = "Mary had a little lamb".split_whitespace();
1243 /// assert_eq!(split.as_str(), "Mary had a little lamb");
1246 /// assert_eq!(split.as_str(), "had a little lamb");
1248 /// split.by_ref().for_each(drop);
1249 /// assert_eq!(split.as_str(), "");
1253 #[unstable(feature = "str_split_whitespace_as_str", issue = "77998")]
1254 pub fn as_str(&self) -> &'a
str {
1255 self.inner
.iter
.as_str()
1259 #[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1260 impl<'a
> Iterator
for SplitAsciiWhitespace
<'a
> {
1261 type Item
= &'a
str;
1264 fn next(&mut self) -> Option
<&'a
str> {
1269 fn size_hint(&self) -> (usize, Option
<usize>) {
1270 self.inner
.size_hint()
1274 fn last(mut self) -> Option
<&'a
str> {
1279 #[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1280 impl<'a
> DoubleEndedIterator
for SplitAsciiWhitespace
<'a
> {
1282 fn next_back(&mut self) -> Option
<&'a
str> {
1283 self.inner
.next_back()
1287 #[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1288 impl FusedIterator
for SplitAsciiWhitespace
<'_
> {}
1290 impl<'a
> SplitAsciiWhitespace
<'a
> {
1291 /// Returns remainder of the splitted string
1296 /// #![feature(str_split_whitespace_as_str)]
1298 /// let mut split = "Mary had a little lamb".split_ascii_whitespace();
1299 /// assert_eq!(split.as_str(), "Mary had a little lamb");
1302 /// assert_eq!(split.as_str(), "had a little lamb");
1304 /// split.by_ref().for_each(drop);
1305 /// assert_eq!(split.as_str(), "");
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
{
1315 // SAFETY: Slice is created from str.
1316 unsafe { crate::str::from_utf8_unchecked(&self.inner.iter.iter.v) }
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;
1325 fn next(&mut self) -> Option
<&'a
str> {
1326 self.0.next_inclusive()
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()
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())
1345 #[stable(feature = "split_inclusive", since = "1.51.0")]
1346 impl<'a
, P
: Pattern
<'a
, Searcher
: ReverseSearcher
<'a
>>> DoubleEndedIterator
1347 for SplitInclusive
<'a
, P
>
1350 fn next_back(&mut self) -> Option
<&'a
str> {
1351 self.0.next_back_inclusive()
1355 #[stable(feature = "split_inclusive", since = "1.51.0")]
1356 impl<'a
, P
: Pattern
<'a
>> FusedIterator
for SplitInclusive
<'a
, P
> {}
1358 impl<'a
, P
: Pattern
<'a
>> SplitInclusive
<'a
, P
> {
1359 /// Returns remainder of the splitted string
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");
1368 /// assert_eq!(split.as_str(), "had a little lamb");
1369 /// split.by_ref().for_each(drop);
1370 /// assert_eq!(split.as_str(), "");
1373 #[unstable(feature = "str_split_inclusive_as_str", issue = "77998")]
1374 pub fn as_str(&self) -> &'a
str {
1379 /// An iterator of [`u16`] over the string encoded as UTF-16.
1381 /// This struct is created by the [`encode_utf16`] method on [`str`].
1382 /// See its documentation for more.
1384 /// [`encode_utf16`]: str::encode_utf16
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,
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()
1399 #[stable(feature = "encode_utf16", since = "1.8.0")]
1400 impl<'a
> Iterator
for EncodeUtf16
<'a
> {
1404 fn next(&mut self) -> Option
<u16> {
1405 if self.extra
!= 0 {
1406 let tmp
= self.extra
;
1411 let mut buf
= [0; 2];
1412 self.chars
.next().map(|ch
| {
1413 let n
= ch
.encode_utf16(&mut buf
).len();
1415 self.extra
= buf
[1];
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)))
1431 #[stable(feature = "fused", since = "1.26.0")]
1432 impl FusedIterator
for EncodeUtf16
<'_
> {}
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
>,
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
>,
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
>,
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
))
1467 #[stable(feature = "str_escape", since = "1.34.0")]
1468 impl<'a
> Iterator
for $Name
<'a
> {
1472 fn next(&mut self) -> Option
<char> { self.inner.next() }
1475 fn size_hint(&self) -> (usize, Option
<usize>) { self.inner.size_hint() }
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
>
1481 self.inner
.try_fold(init
, fold
)
1485 fn fold
<Acc
, Fold
>(self, init
: Acc
, fold
: Fold
) -> Acc
1486 where Fold
: FnMut(Acc
, Self::Item
) -> Acc
,
1488 self.inner
.fold(init
, fold
)
1492 #[stable(feature = "str_escape", since = "1.34.0")]
1493 impl<'a
> FusedIterator
for $Name
<'a
> {}
1497 escape_types_impls
!(EscapeDebug
, EscapeDefault
, EscapeUnicode
);