1 //! Iterators for `str` methods.
4 use crate::fmt::{self, Write};
5 use crate::iter::TrustedRandomAccess;
6 use crate::iter::{Chain, FlatMap, Flatten};
7 use crate::iter::{Copied, Filter, FusedIterator, Map, TrustedLen};
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 let bytes_len = self.iter.len();
51 let mut cont_bytes = 0;
52 for &byte in self.iter {
53 cont_bytes += utf8_is_cont_byte(byte) as usize;
55 bytes_len - cont_bytes
59 fn size_hint(&self) -> (usize, Option<usize>) {
60 let len = self.iter.len();
61 // `(len + 3)` can't overflow, because we know that the `slice::Iter`
62 // belongs to a slice in memory which has a maximum length of
63 // `isize::MAX` (that's well below `usize::MAX`).
64 ((len + 3) / 4, Some(len))
68 fn last(mut self) -> Option<char> {
69 // No need to go through the entire string.
74 #[stable(feature = "chars_debug_impl", since = "1.38.0")]
75 impl fmt::Debug for Chars<'_> {
76 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78 f.debug_list().entries(self.clone()).finish()?;
84 #[stable(feature = "rust1", since = "1.0.0")]
85 impl<'a> DoubleEndedIterator for Chars<'a> {
87 fn next_back(&mut self) -> Option<char> {
88 next_code_point_reverse(&mut self.iter).map(|ch| {
89 // SAFETY: `str` invariant says `ch` is a valid Unicode Scalar Value.
90 unsafe { char::from_u32_unchecked(ch) }
95 #[stable(feature = "fused", since = "1.26.0")]
96 impl FusedIterator for Chars<'_> {}
99 /// Views the underlying data as a subslice of the original data.
101 /// This has the same lifetime as the original slice, and so the
102 /// iterator can continue to be used while this exists.
107 /// let mut chars = "abc".chars();
109 /// assert_eq!(chars.as_str(), "abc");
111 /// assert_eq!(chars.as_str(), "bc");
114 /// assert_eq!(chars.as_str(), "");
116 #[stable(feature = "iter_to_slice", since = "1.4.0")]
118 pub fn as_str(&self) -> &'a str {
119 // SAFETY: `Chars` is only made from a str, which guarantees the iter is valid UTF-8.
120 unsafe { from_utf8_unchecked(self.iter.as_slice()) }
124 /// An iterator over the [`char`]s of a string slice, and their positions.
126 /// This struct is created by the [`char_indices`] method on [`str`].
127 /// See its documentation for more.
129 /// [`char`]: prim@char
130 /// [`char_indices`]: str::char_indices
131 #[derive(Clone, Debug)]
132 #[stable(feature = "rust1", since = "1.0.0")]
133 pub struct CharIndices<'a> {
134 pub(super) front_offset: usize,
135 pub(super) iter: Chars<'a>,
138 #[stable(feature = "rust1", since = "1.0.0")]
139 impl<'a> Iterator for CharIndices<'a> {
140 type Item = (usize, char);
143 fn next(&mut self) -> Option<(usize, char)> {
144 let pre_len = self.iter.iter.len();
145 match self.iter.next() {
148 let index = self.front_offset;
149 let len = self.iter.iter.len();
150 self.front_offset += pre_len - len;
157 fn count(self) -> usize {
162 fn size_hint(&self) -> (usize, Option<usize>) {
163 self.iter.size_hint()
167 fn last(mut self) -> Option<(usize, char)> {
168 // No need to go through the entire string.
173 #[stable(feature = "rust1", since = "1.0.0")]
174 impl<'a> DoubleEndedIterator for CharIndices<'a> {
176 fn next_back(&mut self) -> Option<(usize, char)> {
177 self.iter.next_back().map(|ch| {
178 let index = self.front_offset + self.iter.iter.len();
184 #[stable(feature = "fused", since = "1.26.0")]
185 impl FusedIterator for CharIndices<'_> {}
187 impl<'a> CharIndices<'a> {
188 /// Views the underlying data as a subslice of the original data.
190 /// This has the same lifetime as the original slice, and so the
191 /// iterator can continue to be used while this exists.
192 #[stable(feature = "iter_to_slice", since = "1.4.0")]
194 pub fn as_str(&self) -> &'a str {
199 /// An iterator over the bytes of a string slice.
201 /// This struct is created by the [`bytes`] method on [`str`].
202 /// See its documentation for more.
204 /// [`bytes`]: str::bytes
205 #[stable(feature = "rust1", since = "1.0.0")]
206 #[derive(Clone, Debug)]
207 pub struct Bytes<'a>(pub(super) Copied<slice::Iter<'a, u8>>);
209 #[stable(feature = "rust1", since = "1.0.0")]
210 impl Iterator for Bytes<'_> {
214 fn next(&mut self) -> Option<u8> {
219 fn size_hint(&self) -> (usize, Option<usize>) {
224 fn count(self) -> usize {
229 fn last(self) -> Option<Self::Item> {
234 fn nth(&mut self, n: usize) -> Option<Self::Item> {
239 fn all<F>(&mut self, f: F) -> bool
241 F: FnMut(Self::Item) -> bool,
247 fn any<F>(&mut self, f: F) -> bool
249 F: FnMut(Self::Item) -> bool,
255 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
257 P: FnMut(&Self::Item) -> bool,
259 self.0.find(predicate)
263 fn position<P>(&mut self, predicate: P) -> Option<usize>
265 P: FnMut(Self::Item) -> bool,
267 self.0.position(predicate)
271 fn rposition<P>(&mut self, predicate: P) -> Option<usize>
273 P: FnMut(Self::Item) -> bool,
275 self.0.rposition(predicate)
279 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> u8 {
280 // SAFETY: the caller must uphold the safety contract
281 // for `Iterator::__iterator_get_unchecked`.
282 unsafe { self.0.__iterator_get_unchecked(idx) }
286 #[stable(feature = "rust1", since = "1.0.0")]
287 impl DoubleEndedIterator for Bytes<'_> {
289 fn next_back(&mut self) -> Option<u8> {
294 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
299 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
301 P: FnMut(&Self::Item) -> bool,
303 self.0.rfind(predicate)
307 #[stable(feature = "rust1", since = "1.0.0")]
308 impl ExactSizeIterator for Bytes<'_> {
310 fn len(&self) -> usize {
315 fn is_empty(&self) -> bool {
320 #[stable(feature = "fused", since = "1.26.0")]
321 impl FusedIterator for Bytes<'_> {}
323 #[unstable(feature = "trusted_len", issue = "37572")]
324 unsafe impl TrustedLen for Bytes<'_> {}
327 #[unstable(feature = "trusted_random_access", issue = "none")]
328 unsafe impl TrustedRandomAccess for Bytes<'_> {
330 fn may_have_side_effect() -> bool {
335 /// This macro generates a Clone impl for string pattern API
336 /// wrapper types of the form X<'a, P>
337 macro_rules! derive_pattern_clone {
338 (clone $t:ident with |$s:ident| $e:expr) => {
339 impl<'a, P> Clone for $t<'a, P>
341 P: Pattern<'a, Searcher: Clone>,
343 fn clone(&self) -> Self {
351 /// This macro generates two public iterator structs
352 /// wrapping a private internal one that makes use of the `Pattern` API.
354 /// For all patterns `P: Pattern<'a>` the following items will be
355 /// generated (generics omitted):
357 /// struct $forward_iterator($internal_iterator);
358 /// struct $reverse_iterator($internal_iterator);
360 /// impl Iterator for $forward_iterator
361 /// { /* internal ends up calling Searcher::next_match() */ }
363 /// impl DoubleEndedIterator for $forward_iterator
364 /// where P::Searcher: DoubleEndedSearcher
365 /// { /* internal ends up calling Searcher::next_match_back() */ }
367 /// impl Iterator for $reverse_iterator
368 /// where P::Searcher: ReverseSearcher
369 /// { /* internal ends up calling Searcher::next_match_back() */ }
371 /// impl DoubleEndedIterator for $reverse_iterator
372 /// where P::Searcher: DoubleEndedSearcher
373 /// { /* internal ends up calling Searcher::next_match() */ }
375 /// The internal one is defined outside the macro, and has almost the same
376 /// semantic as a DoubleEndedIterator by delegating to `pattern::Searcher` and
377 /// `pattern::ReverseSearcher` for both forward and reverse iteration.
379 /// "Almost", because a `Searcher` and a `ReverseSearcher` for a given
380 /// `Pattern` might not return the same elements, so actually implementing
381 /// `DoubleEndedIterator` for it would be incorrect.
382 /// (See the docs in `str::pattern` for more details)
384 /// However, the internal struct still represents a single ended iterator from
385 /// either end, and depending on pattern is also a valid double ended iterator,
386 /// so the two wrapper structs implement `Iterator`
387 /// and `DoubleEndedIterator` depending on the concrete pattern type, leading
388 /// to the complex impls seen above.
389 macro_rules! generate_pattern_iterators {
393 $(#[$forward_iterator_attribute:meta])*
394 struct $forward_iterator:ident;
398 $(#[$reverse_iterator_attribute:meta])*
399 struct $reverse_iterator:ident;
401 // Stability of all generated items
403 $(#[$common_stability_attribute:meta])*
405 // Internal almost-iterator that is being delegated to
407 $internal_iterator:ident yielding ($iterty:ty);
409 // Kind of delegation - either single ended or double ended
412 $(#[$forward_iterator_attribute])*
413 $(#[$common_stability_attribute])*
414 pub struct $forward_iterator<'a, P: Pattern<'a>>(pub(super) $internal_iterator<'a, P>);
416 $(#[$common_stability_attribute])*
417 impl<'a, P> fmt::Debug for $forward_iterator<'a, P>
419 P: Pattern<'a, Searcher: fmt::Debug>,
421 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
422 f.debug_tuple(stringify!($forward_iterator))
428 $(#[$common_stability_attribute])*
429 impl<'a, P: Pattern<'a>> Iterator for $forward_iterator<'a, P> {
433 fn next(&mut self) -> Option<$iterty> {
438 $(#[$common_stability_attribute])*
439 impl<'a, P> Clone for $forward_iterator<'a, P>
441 P: Pattern<'a, Searcher: Clone>,
443 fn clone(&self) -> Self {
444 $forward_iterator(self.0.clone())
448 $(#[$reverse_iterator_attribute])*
449 $(#[$common_stability_attribute])*
450 pub struct $reverse_iterator<'a, P: Pattern<'a>>(pub(super) $internal_iterator<'a, P>);
452 $(#[$common_stability_attribute])*
453 impl<'a, P> fmt::Debug for $reverse_iterator<'a, P>
455 P: Pattern<'a, Searcher: fmt::Debug>,
457 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
458 f.debug_tuple(stringify!($reverse_iterator))
464 $(#[$common_stability_attribute])*
465 impl<'a, P> Iterator for $reverse_iterator<'a, P>
467 P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
472 fn next(&mut self) -> Option<$iterty> {
477 $(#[$common_stability_attribute])*
478 impl<'a, P> Clone for $reverse_iterator<'a, P>
480 P: Pattern<'a, Searcher: Clone>,
482 fn clone(&self) -> Self {
483 $reverse_iterator(self.0.clone())
487 #[stable(feature = "fused", since = "1.26.0")]
488 impl<'a, P: Pattern<'a>> FusedIterator for $forward_iterator<'a, P> {}
490 #[stable(feature = "fused", since = "1.26.0")]
491 impl<'a, P> FusedIterator for $reverse_iterator<'a, P>
493 P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
496 generate_pattern_iterators!($($t)* with $(#[$common_stability_attribute])*,
498 $reverse_iterator, $iterty);
501 double ended; with $(#[$common_stability_attribute:meta])*,
502 $forward_iterator:ident,
503 $reverse_iterator:ident, $iterty:ty
505 $(#[$common_stability_attribute])*
506 impl<'a, P> DoubleEndedIterator for $forward_iterator<'a, P>
508 P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,
511 fn next_back(&mut self) -> Option<$iterty> {
516 $(#[$common_stability_attribute])*
517 impl<'a, P> DoubleEndedIterator for $reverse_iterator<'a, P>
519 P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,
522 fn next_back(&mut self) -> Option<$iterty> {
528 single ended; with $(#[$common_stability_attribute:meta])*,
529 $forward_iterator:ident,
530 $reverse_iterator:ident, $iterty:ty
534 derive_pattern_clone! {
536 with |s| SplitInternal { matcher: s.matcher.clone(), ..*s }
539 pub(super) struct SplitInternal<'a, P: Pattern<'a>> {
540 pub(super) start: usize,
541 pub(super) end: usize,
542 pub(super) matcher: P::Searcher,
543 pub(super) allow_trailing_empty: bool,
544 pub(super) finished: bool,
547 impl<'a, P> fmt::Debug for SplitInternal<'a, P>
549 P: Pattern<'a, Searcher: fmt::Debug>,
551 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
552 f.debug_struct("SplitInternal")
553 .field("start", &self.start)
554 .field("end", &self.end)
555 .field("matcher", &self.matcher)
556 .field("allow_trailing_empty", &self.allow_trailing_empty)
557 .field("finished", &self.finished)
562 impl<'a, P: Pattern<'a>> SplitInternal<'a, P> {
564 fn get_end(&mut self) -> Option<&'a str> {
565 if !self.finished && (self.allow_trailing_empty || self.end - self.start > 0) {
566 self.finished = true;
567 // SAFETY: `self.start` and `self.end` always lie on unicode boundaries.
569 let string = self.matcher.haystack().get_unchecked(self.start..self.end);
578 fn next(&mut self) -> Option<&'a str> {
583 let haystack = self.matcher.haystack();
584 match self.matcher.next_match() {
585 // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries.
586 Some((a, b)) => unsafe {
587 let elt = haystack.get_unchecked(self.start..a);
591 None => self.get_end(),
596 fn next_inclusive(&mut self) -> Option<&'a str> {
601 let haystack = self.matcher.haystack();
602 match self.matcher.next_match() {
603 // SAFETY: `Searcher` guarantees that `b` lies on unicode boundary,
604 // and self.start is either the start of the original string,
605 // or `b` was assigned to it, so it also lies on unicode boundary.
606 Some((_, b)) => unsafe {
607 let elt = haystack.get_unchecked(self.start..b);
611 None => self.get_end(),
616 fn next_back(&mut self) -> Option<&'a str>
618 P::Searcher: ReverseSearcher<'a>,
624 if !self.allow_trailing_empty {
625 self.allow_trailing_empty = true;
626 match self.next_back() {
627 Some(elt) if !elt.is_empty() => return Some(elt),
636 let haystack = self.matcher.haystack();
637 match self.matcher.next_match_back() {
638 // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries.
639 Some((a, b)) => unsafe {
640 let elt = haystack.get_unchecked(b..self.end);
644 // SAFETY: `self.start` and `self.end` always lie on unicode boundaries.
646 self.finished = true;
647 Some(haystack.get_unchecked(self.start..self.end))
653 fn next_back_inclusive(&mut self) -> Option<&'a str>
655 P::Searcher: ReverseSearcher<'a>,
661 if !self.allow_trailing_empty {
662 self.allow_trailing_empty = true;
663 match self.next_back_inclusive() {
664 Some(elt) if !elt.is_empty() => return Some(elt),
673 let haystack = self.matcher.haystack();
674 match self.matcher.next_match_back() {
675 // SAFETY: `Searcher` guarantees that `b` lies on unicode boundary,
676 // and self.end is either the end of the original string,
677 // or `b` was assigned to it, so it also lies on unicode boundary.
678 Some((_, b)) => unsafe {
679 let elt = haystack.get_unchecked(b..self.end);
683 // SAFETY: self.start is either the start of the original string,
684 // or start of a substring that represents the part of the string that hasn't
685 // iterated yet. Either way, it is guaranteed to lie on unicode boundary.
686 // self.end is either the end of the original string,
687 // or `b` was assigned to it, so it also lies on unicode boundary.
689 self.finished = true;
690 Some(haystack.get_unchecked(self.start..self.end))
696 fn as_str(&self) -> &'a str {
697 // `Self::get_end` doesn't change `self.start`
702 // SAFETY: `self.start` and `self.end` always lie on unicode boundaries.
703 unsafe { self.matcher.haystack().get_unchecked(self.start..self.end) }
707 generate_pattern_iterators! {
709 /// Created with the method [`split`].
711 /// [`split`]: str::split
714 /// Created with the method [`rsplit`].
716 /// [`rsplit`]: str::rsplit
719 #[stable(feature = "rust1", since = "1.0.0")]
721 SplitInternal yielding (&'a str);
722 delegate double ended;
725 impl<'a, P: Pattern<'a>> Split<'a, P> {
726 /// Returns remainder of the splitted string
731 /// #![feature(str_split_as_str)]
732 /// let mut split = "Mary had a little lamb".split(' ');
733 /// assert_eq!(split.as_str(), "Mary had a little lamb");
735 /// assert_eq!(split.as_str(), "had a little lamb");
736 /// split.by_ref().for_each(drop);
737 /// assert_eq!(split.as_str(), "");
740 #[unstable(feature = "str_split_as_str", issue = "77998")]
741 pub fn as_str(&self) -> &'a str {
746 impl<'a, P: Pattern<'a>> RSplit<'a, P> {
747 /// Returns remainder of the splitted string
752 /// #![feature(str_split_as_str)]
753 /// let mut split = "Mary had a little lamb".rsplit(' ');
754 /// assert_eq!(split.as_str(), "Mary had a little lamb");
756 /// assert_eq!(split.as_str(), "Mary had a little");
757 /// split.by_ref().for_each(drop);
758 /// assert_eq!(split.as_str(), "");
761 #[unstable(feature = "str_split_as_str", issue = "77998")]
762 pub fn as_str(&self) -> &'a str {
767 generate_pattern_iterators! {
769 /// Created with the method [`split_terminator`].
771 /// [`split_terminator`]: str::split_terminator
772 struct SplitTerminator;
774 /// Created with the method [`rsplit_terminator`].
776 /// [`rsplit_terminator`]: str::rsplit_terminator
777 struct RSplitTerminator;
779 #[stable(feature = "rust1", since = "1.0.0")]
781 SplitInternal yielding (&'a str);
782 delegate double ended;
785 impl<'a, P: Pattern<'a>> SplitTerminator<'a, P> {
786 /// Returns remainder of the splitted string
791 /// #![feature(str_split_as_str)]
792 /// let mut split = "A..B..".split_terminator('.');
793 /// assert_eq!(split.as_str(), "A..B..");
795 /// assert_eq!(split.as_str(), ".B..");
796 /// split.by_ref().for_each(drop);
797 /// assert_eq!(split.as_str(), "");
800 #[unstable(feature = "str_split_as_str", issue = "77998")]
801 pub fn as_str(&self) -> &'a str {
806 impl<'a, P: Pattern<'a>> RSplitTerminator<'a, P> {
807 /// Returns remainder of the splitted string
812 /// #![feature(str_split_as_str)]
813 /// let mut split = "A..B..".rsplit_terminator('.');
814 /// assert_eq!(split.as_str(), "A..B..");
816 /// assert_eq!(split.as_str(), "A..B");
817 /// split.by_ref().for_each(drop);
818 /// assert_eq!(split.as_str(), "");
821 #[unstable(feature = "str_split_as_str", issue = "77998")]
822 pub fn as_str(&self) -> &'a str {
827 derive_pattern_clone! {
829 with |s| SplitNInternal { iter: s.iter.clone(), ..*s }
832 pub(super) struct SplitNInternal<'a, P: Pattern<'a>> {
833 pub(super) iter: SplitInternal<'a, P>,
834 /// The number of splits remaining
835 pub(super) count: usize,
838 impl<'a, P> fmt::Debug for SplitNInternal<'a, P>
840 P: Pattern<'a, Searcher: fmt::Debug>,
842 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
843 f.debug_struct("SplitNInternal")
844 .field("iter", &self.iter)
845 .field("count", &self.count)
850 impl<'a, P: Pattern<'a>> SplitNInternal<'a, P> {
852 fn next(&mut self) -> Option<&'a str> {
867 fn next_back(&mut self) -> Option<&'a str>
869 P::Searcher: ReverseSearcher<'a>,
879 self.iter.next_back()
885 fn as_str(&self) -> &'a str {
890 generate_pattern_iterators! {
892 /// Created with the method [`splitn`].
894 /// [`splitn`]: str::splitn
897 /// Created with the method [`rsplitn`].
899 /// [`rsplitn`]: str::rsplitn
902 #[stable(feature = "rust1", since = "1.0.0")]
904 SplitNInternal yielding (&'a str);
905 delegate single ended;
908 impl<'a, P: Pattern<'a>> SplitN<'a, P> {
909 /// Returns remainder of the splitted string
914 /// #![feature(str_split_as_str)]
915 /// let mut split = "Mary had a little lamb".splitn(3, ' ');
916 /// assert_eq!(split.as_str(), "Mary had a little lamb");
918 /// assert_eq!(split.as_str(), "had a little lamb");
919 /// split.by_ref().for_each(drop);
920 /// assert_eq!(split.as_str(), "");
923 #[unstable(feature = "str_split_as_str", issue = "77998")]
924 pub fn as_str(&self) -> &'a str {
929 impl<'a, P: Pattern<'a>> RSplitN<'a, P> {
930 /// Returns remainder of the splitted string
935 /// #![feature(str_split_as_str)]
936 /// let mut split = "Mary had a little lamb".rsplitn(3, ' ');
937 /// assert_eq!(split.as_str(), "Mary had a little lamb");
939 /// assert_eq!(split.as_str(), "Mary had a little");
940 /// split.by_ref().for_each(drop);
941 /// assert_eq!(split.as_str(), "");
944 #[unstable(feature = "str_split_as_str", issue = "77998")]
945 pub fn as_str(&self) -> &'a str {
950 derive_pattern_clone! {
951 clone MatchIndicesInternal
952 with |s| MatchIndicesInternal(s.0.clone())
955 pub(super) struct MatchIndicesInternal<'a, P: Pattern<'a>>(pub(super) P::Searcher);
957 impl<'a, P> fmt::Debug for MatchIndicesInternal<'a, P>
959 P: Pattern<'a, Searcher: fmt::Debug>,
961 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
962 f.debug_tuple("MatchIndicesInternal").field(&self.0).finish()
966 impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> {
968 fn next(&mut self) -> Option<(usize, &'a str)> {
971 // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
972 .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) })
976 fn next_back(&mut self) -> Option<(usize, &'a str)>
978 P::Searcher: ReverseSearcher<'a>,
982 // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
983 .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) })
987 generate_pattern_iterators! {
989 /// Created with the method [`match_indices`].
991 /// [`match_indices`]: str::match_indices
994 /// Created with the method [`rmatch_indices`].
996 /// [`rmatch_indices`]: str::rmatch_indices
997 struct RMatchIndices;
999 #[stable(feature = "str_match_indices", since = "1.5.0")]
1001 MatchIndicesInternal yielding ((usize, &'a str));
1002 delegate double ended;
1005 derive_pattern_clone! {
1006 clone MatchesInternal
1007 with |s| MatchesInternal(s.0.clone())
1010 pub(super) struct MatchesInternal<'a, P: Pattern<'a>>(pub(super) P::Searcher);
1012 impl<'a, P> fmt::Debug for MatchesInternal<'a, P>
1014 P: Pattern<'a, Searcher: fmt::Debug>,
1016 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1017 f.debug_tuple("MatchesInternal").field(&self.0).finish()
1021 impl<'a, P: Pattern<'a>> MatchesInternal<'a, P> {
1023 fn next(&mut self) -> Option<&'a str> {
1024 // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
1025 self.0.next_match().map(|(a, b)| unsafe {
1026 // Indices are known to be on utf8 boundaries
1027 self.0.haystack().get_unchecked(a..b)
1032 fn next_back(&mut self) -> Option<&'a str>
1034 P::Searcher: ReverseSearcher<'a>,
1036 // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
1037 self.0.next_match_back().map(|(a, b)| unsafe {
1038 // Indices are known to be on utf8 boundaries
1039 self.0.haystack().get_unchecked(a..b)
1044 generate_pattern_iterators! {
1046 /// Created with the method [`matches`].
1048 /// [`matches`]: str::matches
1051 /// Created with the method [`rmatches`].
1053 /// [`rmatches`]: str::rmatches
1056 #[stable(feature = "str_matches", since = "1.2.0")]
1058 MatchesInternal yielding (&'a str);
1059 delegate double ended;
1062 /// An iterator over the lines of a string, as string slices.
1064 /// This struct is created with the [`lines`] method on [`str`].
1065 /// See its documentation for more.
1067 /// [`lines`]: str::lines
1068 #[stable(feature = "rust1", since = "1.0.0")]
1069 #[derive(Clone, Debug)]
1070 pub struct Lines<'a>(pub(super) Map<SplitTerminator<'a, char>, LinesAnyMap>);
1072 #[stable(feature = "rust1", since = "1.0.0")]
1073 impl<'a> Iterator for Lines<'a> {
1074 type Item = &'a str;
1077 fn next(&mut self) -> Option<&'a str> {
1082 fn size_hint(&self) -> (usize, Option<usize>) {
1087 fn last(mut self) -> Option<&'a str> {
1092 #[stable(feature = "rust1", since = "1.0.0")]
1093 impl<'a> DoubleEndedIterator for Lines<'a> {
1095 fn next_back(&mut self) -> Option<&'a str> {
1100 #[stable(feature = "fused", since = "1.26.0")]
1101 impl FusedIterator for Lines<'_> {}
1103 /// Created with the method [`lines_any`].
1105 /// [`lines_any`]: str::lines_any
1106 #[stable(feature = "rust1", since = "1.0.0")]
1107 #[rustc_deprecated(since = "1.4.0", reason = "use lines()/Lines instead now")]
1108 #[derive(Clone, Debug)]
1109 #[allow(deprecated)]
1110 pub struct LinesAny<'a>(pub(super) Lines<'a>);
1112 #[stable(feature = "rust1", since = "1.0.0")]
1113 #[allow(deprecated)]
1114 impl<'a> Iterator for LinesAny<'a> {
1115 type Item = &'a str;
1118 fn next(&mut self) -> Option<&'a str> {
1123 fn size_hint(&self) -> (usize, Option<usize>) {
1128 #[stable(feature = "rust1", since = "1.0.0")]
1129 #[allow(deprecated)]
1130 impl<'a> DoubleEndedIterator for LinesAny<'a> {
1132 fn next_back(&mut self) -> Option<&'a str> {
1137 #[stable(feature = "fused", since = "1.26.0")]
1138 #[allow(deprecated)]
1139 impl FusedIterator for LinesAny<'_> {}
1141 /// An iterator over the non-whitespace substrings of a string,
1142 /// separated by any amount of whitespace.
1144 /// This struct is created by the [`split_whitespace`] method on [`str`].
1145 /// See its documentation for more.
1147 /// [`split_whitespace`]: str::split_whitespace
1148 #[stable(feature = "split_whitespace", since = "1.1.0")]
1149 #[derive(Clone, Debug)]
1150 pub struct SplitWhitespace<'a> {
1151 pub(super) inner: Filter<Split<'a, IsWhitespace>, IsNotEmpty>,
1154 /// An iterator over the non-ASCII-whitespace substrings of a string,
1155 /// separated by any amount of ASCII whitespace.
1157 /// This struct is created by the [`split_ascii_whitespace`] method on [`str`].
1158 /// See its documentation for more.
1160 /// [`split_ascii_whitespace`]: str::split_ascii_whitespace
1161 #[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1162 #[derive(Clone, Debug)]
1163 pub struct SplitAsciiWhitespace<'a> {
1165 Map<Filter<SliceSplit<'a, u8, IsAsciiWhitespace>, BytesIsNotEmpty>, UnsafeBytesToStr>,
1168 /// An iterator over the substrings of a string,
1169 /// terminated by a substring matching to a predicate function
1170 /// Unlike `Split`, it contains the matched part as a terminator
1171 /// of the subslice.
1173 /// This struct is created by the [`split_inclusive`] method on [`str`].
1174 /// See its documentation for more.
1176 /// [`split_inclusive`]: str::split_inclusive
1177 #[stable(feature = "split_inclusive", since = "1.49.0")]
1178 pub struct SplitInclusive<'a, P: Pattern<'a>>(pub(super) SplitInternal<'a, P>);
1180 #[stable(feature = "split_whitespace", since = "1.1.0")]
1181 impl<'a> Iterator for SplitWhitespace<'a> {
1182 type Item = &'a str;
1185 fn next(&mut self) -> Option<&'a str> {
1190 fn size_hint(&self) -> (usize, Option<usize>) {
1191 self.inner.size_hint()
1195 fn last(mut self) -> Option<&'a str> {
1200 #[stable(feature = "split_whitespace", since = "1.1.0")]
1201 impl<'a> DoubleEndedIterator for SplitWhitespace<'a> {
1203 fn next_back(&mut self) -> Option<&'a str> {
1204 self.inner.next_back()
1208 #[stable(feature = "fused", since = "1.26.0")]
1209 impl FusedIterator for SplitWhitespace<'_> {}
1211 #[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1212 impl<'a> Iterator for SplitAsciiWhitespace<'a> {
1213 type Item = &'a str;
1216 fn next(&mut self) -> Option<&'a str> {
1221 fn size_hint(&self) -> (usize, Option<usize>) {
1222 self.inner.size_hint()
1226 fn last(mut self) -> Option<&'a str> {
1231 #[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1232 impl<'a> DoubleEndedIterator for SplitAsciiWhitespace<'a> {
1234 fn next_back(&mut self) -> Option<&'a str> {
1235 self.inner.next_back()
1239 #[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1240 impl FusedIterator for SplitAsciiWhitespace<'_> {}
1242 #[stable(feature = "split_inclusive", since = "1.49.0")]
1243 impl<'a, P: Pattern<'a>> Iterator for SplitInclusive<'a, P> {
1244 type Item = &'a str;
1247 fn next(&mut self) -> Option<&'a str> {
1248 self.0.next_inclusive()
1252 #[stable(feature = "split_inclusive", since = "1.49.0")]
1253 impl<'a, P: Pattern<'a, Searcher: fmt::Debug>> fmt::Debug for SplitInclusive<'a, P> {
1254 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1255 f.debug_struct("SplitInclusive").field("0", &self.0).finish()
1259 // FIXME(#26925) Remove in favor of `#[derive(Clone)]`
1260 #[stable(feature = "split_inclusive", since = "1.49.0")]
1261 impl<'a, P: Pattern<'a, Searcher: Clone>> Clone for SplitInclusive<'a, P> {
1262 fn clone(&self) -> Self {
1263 SplitInclusive(self.0.clone())
1267 #[stable(feature = "split_inclusive", since = "1.49.0")]
1268 impl<'a, P: Pattern<'a, Searcher: ReverseSearcher<'a>>> DoubleEndedIterator
1269 for SplitInclusive<'a, P>
1272 fn next_back(&mut self) -> Option<&'a str> {
1273 self.0.next_back_inclusive()
1277 #[stable(feature = "split_inclusive", since = "1.49.0")]
1278 impl<'a, P: Pattern<'a>> FusedIterator for SplitInclusive<'a, P> {}
1280 impl<'a, P: Pattern<'a>> SplitInclusive<'a, P> {
1281 /// Returns remainder of the splitted string
1286 /// #![feature(str_split_inclusive_as_str)]
1287 /// #![feature(split_inclusive)]
1288 /// let mut split = "Mary had a little lamb".split_inclusive(' ');
1289 /// assert_eq!(split.as_str(), "Mary had a little lamb");
1291 /// assert_eq!(split.as_str(), "had a little lamb");
1292 /// split.by_ref().for_each(drop);
1293 /// assert_eq!(split.as_str(), "");
1296 #[unstable(feature = "str_split_inclusive_as_str", issue = "77998")]
1297 pub fn as_str(&self) -> &'a str {
1302 /// An iterator of [`u16`] over the string encoded as UTF-16.
1304 /// This struct is created by the [`encode_utf16`] method on [`str`].
1305 /// See its documentation for more.
1307 /// [`encode_utf16`]: str::encode_utf16
1309 #[stable(feature = "encode_utf16", since = "1.8.0")]
1310 pub struct EncodeUtf16<'a> {
1311 pub(super) chars: Chars<'a>,
1312 pub(super) extra: u16,
1315 #[stable(feature = "collection_debug", since = "1.17.0")]
1316 impl fmt::Debug for EncodeUtf16<'_> {
1317 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1318 f.pad("EncodeUtf16 { .. }")
1322 #[stable(feature = "encode_utf16", since = "1.8.0")]
1323 impl<'a> Iterator for EncodeUtf16<'a> {
1327 fn next(&mut self) -> Option<u16> {
1328 if self.extra != 0 {
1329 let tmp = self.extra;
1334 let mut buf = [0; 2];
1335 self.chars.next().map(|ch| {
1336 let n = ch.encode_utf16(&mut buf).len();
1338 self.extra = buf[1];
1345 fn size_hint(&self) -> (usize, Option<usize>) {
1346 let (low, high) = self.chars.size_hint();
1347 // every char gets either one u16 or two u16,
1348 // so this iterator is between 1 or 2 times as
1349 // long as the underlying iterator.
1350 (low, high.and_then(|n| n.checked_mul(2)))
1354 #[stable(feature = "fused", since = "1.26.0")]
1355 impl FusedIterator for EncodeUtf16<'_> {}
1357 /// The return type of [`str::escape_debug`].
1358 #[stable(feature = "str_escape", since = "1.34.0")]
1359 #[derive(Clone, Debug)]
1360 pub struct EscapeDebug<'a> {
1361 pub(super) inner: Chain<
1362 Flatten<option::IntoIter<char::EscapeDebug>>,
1363 FlatMap<Chars<'a>, char::EscapeDebug, CharEscapeDebugContinue>,
1367 /// The return type of [`str::escape_default`].
1368 #[stable(feature = "str_escape", since = "1.34.0")]
1369 #[derive(Clone, Debug)]
1370 pub struct EscapeDefault<'a> {
1371 pub(super) inner: FlatMap<Chars<'a>, char::EscapeDefault, CharEscapeDefault>,
1374 /// The return type of [`str::escape_unicode`].
1375 #[stable(feature = "str_escape", since = "1.34.0")]
1376 #[derive(Clone, Debug)]
1377 pub struct EscapeUnicode<'a> {
1378 pub(super) inner: FlatMap<Chars<'a>, char::EscapeUnicode, CharEscapeUnicode>,
1381 macro_rules! escape_types_impls {
1382 ($( $Name: ident ),+) => {$(
1383 #[stable(feature = "str_escape", since = "1.34.0")]
1384 impl<'a> fmt::Display for $Name<'a> {
1385 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1386 self.clone().try_for_each(|c| f.write_char(c))
1390 #[stable(feature = "str_escape", since = "1.34.0")]
1391 impl<'a> Iterator for $Name<'a> {
1395 fn next(&mut self) -> Option<char> { self.inner.next() }
1398 fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
1401 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
1402 Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
1404 self.inner.try_fold(init, fold)
1408 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
1409 where Fold: FnMut(Acc, Self::Item) -> Acc,
1411 self.inner.fold(init, fold)
1415 #[stable(feature = "str_escape", since = "1.34.0")]
1416 impl<'a> FusedIterator for $Name<'a> {}
1420 escape_types_impls!(EscapeDebug, EscapeDefault, EscapeUnicode);