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 #[must_use = "iterators are lazy and do nothing unless consumed"]
31 #[stable(feature = "rust1", since = "1.0.0")]
32 pub struct Chars<'a> {
33 pub(super) iter: slice::Iter<'a, u8>,
36 #[stable(feature = "rust1", since = "1.0.0")]
37 impl<'a> Iterator for Chars<'a> {
41 fn next(&mut self) -> Option<char> {
42 next_code_point(&mut self.iter).map(|ch| {
43 // SAFETY: `str` invariant says `ch` is a valid Unicode Scalar Value.
44 unsafe { char::from_u32_unchecked(ch) }
49 fn count(self) -> usize {
50 // length in `char` is equal to the number of non-continuation bytes
51 self.iter.filter(|&&byte| !utf8_is_cont_byte(byte)).count()
55 fn size_hint(&self) -> (usize, Option<usize>) {
56 let len = self.iter.len();
57 // `(len + 3)` can't overflow, because we know that the `slice::Iter`
58 // belongs to a slice in memory which has a maximum length of
59 // `isize::MAX` (that's well below `usize::MAX`).
60 ((len + 3) / 4, Some(len))
64 fn last(mut self) -> Option<char> {
65 // No need to go through the entire string.
70 #[stable(feature = "chars_debug_impl", since = "1.38.0")]
71 impl fmt::Debug for Chars<'_> {
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 f.debug_list().entries(self.clone()).finish()?;
80 #[stable(feature = "rust1", since = "1.0.0")]
81 impl<'a> DoubleEndedIterator for Chars<'a> {
83 fn next_back(&mut self) -> Option<char> {
84 next_code_point_reverse(&mut self.iter).map(|ch| {
85 // SAFETY: `str` invariant says `ch` is a valid Unicode Scalar Value.
86 unsafe { char::from_u32_unchecked(ch) }
91 #[stable(feature = "fused", since = "1.26.0")]
92 impl FusedIterator for Chars<'_> {}
95 /// Views the underlying data as a subslice of the original data.
97 /// This has the same lifetime as the original slice, and so the
98 /// iterator can continue to be used while this exists.
103 /// let mut chars = "abc".chars();
105 /// assert_eq!(chars.as_str(), "abc");
107 /// assert_eq!(chars.as_str(), "bc");
110 /// assert_eq!(chars.as_str(), "");
112 #[stable(feature = "iter_to_slice", since = "1.4.0")]
115 pub fn as_str(&self) -> &'a str {
116 // SAFETY: `Chars` is only made from a str, which guarantees the iter is valid UTF-8.
117 unsafe { from_utf8_unchecked(self.iter.as_slice()) }
121 /// An iterator over the [`char`]s of a string slice, and their positions.
123 /// This struct is created by the [`char_indices`] method on [`str`].
124 /// See its documentation for more.
126 /// [`char`]: prim@char
127 /// [`char_indices`]: str::char_indices
128 #[derive(Clone, Debug)]
129 #[must_use = "iterators are lazy and do nothing unless consumed"]
130 #[stable(feature = "rust1", since = "1.0.0")]
131 pub struct CharIndices<'a> {
132 pub(super) front_offset: usize,
133 pub(super) iter: Chars<'a>,
136 #[stable(feature = "rust1", since = "1.0.0")]
137 impl<'a> Iterator for CharIndices<'a> {
138 type Item = (usize, char);
141 fn next(&mut self) -> Option<(usize, char)> {
142 let pre_len = self.iter.iter.len();
143 match self.iter.next() {
146 let index = self.front_offset;
147 let len = self.iter.iter.len();
148 self.front_offset += pre_len - len;
155 fn count(self) -> usize {
160 fn size_hint(&self) -> (usize, Option<usize>) {
161 self.iter.size_hint()
165 fn last(mut self) -> Option<(usize, char)> {
166 // No need to go through the entire string.
171 #[stable(feature = "rust1", since = "1.0.0")]
172 impl<'a> DoubleEndedIterator for CharIndices<'a> {
174 fn next_back(&mut self) -> Option<(usize, char)> {
175 self.iter.next_back().map(|ch| {
176 let index = self.front_offset + self.iter.iter.len();
182 #[stable(feature = "fused", since = "1.26.0")]
183 impl FusedIterator for CharIndices<'_> {}
185 impl<'a> CharIndices<'a> {
186 /// Views the underlying data as a subslice of the original data.
188 /// This has the same lifetime as the original slice, and so the
189 /// iterator can continue to be used while this exists.
190 #[stable(feature = "iter_to_slice", since = "1.4.0")]
193 pub fn as_str(&self) -> &'a str {
197 /// Returns the byte position of the next character, or the length
198 /// of the underlying string if there are no more characters.
203 /// #![feature(char_indices_offset)]
204 /// let mut chars = "a楽".char_indices();
206 /// assert_eq!(chars.offset(), 0);
207 /// assert_eq!(chars.next(), Some((0, 'a')));
209 /// assert_eq!(chars.offset(), 1);
210 /// assert_eq!(chars.next(), Some((1, '楽')));
212 /// assert_eq!(chars.offset(), 4);
213 /// assert_eq!(chars.next(), None);
217 #[unstable(feature = "char_indices_offset", issue = "83871")]
218 pub fn offset(&self) -> usize {
223 /// An iterator over the bytes of a string slice.
225 /// This struct is created by the [`bytes`] method on [`str`].
226 /// See its documentation for more.
228 /// [`bytes`]: str::bytes
229 #[must_use = "iterators are lazy and do nothing unless consumed"]
230 #[stable(feature = "rust1", since = "1.0.0")]
231 #[derive(Clone, Debug)]
232 pub struct Bytes<'a>(pub(super) Copied<slice::Iter<'a, u8>>);
234 #[stable(feature = "rust1", since = "1.0.0")]
235 impl Iterator for Bytes<'_> {
239 fn next(&mut self) -> Option<u8> {
244 fn size_hint(&self) -> (usize, Option<usize>) {
249 fn count(self) -> usize {
254 fn last(self) -> Option<Self::Item> {
259 fn nth(&mut self, n: usize) -> Option<Self::Item> {
264 fn all<F>(&mut self, f: F) -> bool
266 F: FnMut(Self::Item) -> bool,
272 fn any<F>(&mut self, f: F) -> bool
274 F: FnMut(Self::Item) -> bool,
280 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
282 P: FnMut(&Self::Item) -> bool,
284 self.0.find(predicate)
288 fn position<P>(&mut self, predicate: P) -> Option<usize>
290 P: FnMut(Self::Item) -> bool,
292 self.0.position(predicate)
296 fn rposition<P>(&mut self, predicate: P) -> Option<usize>
298 P: FnMut(Self::Item) -> bool,
300 self.0.rposition(predicate)
305 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> u8 {
306 // SAFETY: the caller must uphold the safety contract
307 // for `Iterator::__iterator_get_unchecked`.
308 unsafe { self.0.__iterator_get_unchecked(idx) }
312 #[stable(feature = "rust1", since = "1.0.0")]
313 impl DoubleEndedIterator for Bytes<'_> {
315 fn next_back(&mut self) -> Option<u8> {
320 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
325 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
327 P: FnMut(&Self::Item) -> bool,
329 self.0.rfind(predicate)
333 #[stable(feature = "rust1", since = "1.0.0")]
334 impl ExactSizeIterator for Bytes<'_> {
336 fn len(&self) -> usize {
341 fn is_empty(&self) -> bool {
346 #[stable(feature = "fused", since = "1.26.0")]
347 impl FusedIterator for Bytes<'_> {}
349 #[unstable(feature = "trusted_len", issue = "37572")]
350 unsafe impl TrustedLen for Bytes<'_> {}
353 #[unstable(feature = "trusted_random_access", issue = "none")]
354 unsafe impl TrustedRandomAccess for Bytes<'_> {}
357 #[unstable(feature = "trusted_random_access", issue = "none")]
358 unsafe impl TrustedRandomAccessNoCoerce for Bytes<'_> {
359 const MAY_HAVE_SIDE_EFFECT: bool = false;
362 /// This macro generates a Clone impl for string pattern API
363 /// wrapper types of the form X<'a, P>
364 macro_rules! derive_pattern_clone {
365 (clone $t:ident with |$s:ident| $e:expr) => {
366 impl<'a, P> Clone for $t<'a, P>
368 P: Pattern<'a, Searcher: Clone>,
370 fn clone(&self) -> Self {
378 /// This macro generates two public iterator structs
379 /// wrapping a private internal one that makes use of the `Pattern` API.
381 /// For all patterns `P: Pattern<'a>` the following items will be
382 /// generated (generics omitted):
384 /// struct $forward_iterator($internal_iterator);
385 /// struct $reverse_iterator($internal_iterator);
387 /// impl Iterator for $forward_iterator
388 /// { /* internal ends up calling Searcher::next_match() */ }
390 /// impl DoubleEndedIterator for $forward_iterator
391 /// where P::Searcher: DoubleEndedSearcher
392 /// { /* internal ends up calling Searcher::next_match_back() */ }
394 /// impl Iterator for $reverse_iterator
395 /// where P::Searcher: ReverseSearcher
396 /// { /* internal ends up calling Searcher::next_match_back() */ }
398 /// impl DoubleEndedIterator for $reverse_iterator
399 /// where P::Searcher: DoubleEndedSearcher
400 /// { /* internal ends up calling Searcher::next_match() */ }
402 /// The internal one is defined outside the macro, and has almost the same
403 /// semantic as a DoubleEndedIterator by delegating to `pattern::Searcher` and
404 /// `pattern::ReverseSearcher` for both forward and reverse iteration.
406 /// "Almost", because a `Searcher` and a `ReverseSearcher` for a given
407 /// `Pattern` might not return the same elements, so actually implementing
408 /// `DoubleEndedIterator` for it would be incorrect.
409 /// (See the docs in `str::pattern` for more details)
411 /// However, the internal struct still represents a single ended iterator from
412 /// either end, and depending on pattern is also a valid double ended iterator,
413 /// so the two wrapper structs implement `Iterator`
414 /// and `DoubleEndedIterator` depending on the concrete pattern type, leading
415 /// to the complex impls seen above.
416 macro_rules! generate_pattern_iterators {
420 $(#[$forward_iterator_attribute:meta])*
421 struct $forward_iterator:ident;
425 $(#[$reverse_iterator_attribute:meta])*
426 struct $reverse_iterator:ident;
428 // Stability of all generated items
430 $(#[$common_stability_attribute:meta])*
432 // Internal almost-iterator that is being delegated to
434 $internal_iterator:ident yielding ($iterty:ty);
436 // Kind of delegation - either single ended or double ended
439 $(#[$forward_iterator_attribute])*
440 $(#[$common_stability_attribute])*
441 pub struct $forward_iterator<'a, P: Pattern<'a>>(pub(super) $internal_iterator<'a, P>);
443 $(#[$common_stability_attribute])*
444 impl<'a, P> fmt::Debug for $forward_iterator<'a, P>
446 P: Pattern<'a, Searcher: fmt::Debug>,
448 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
449 f.debug_tuple(stringify!($forward_iterator))
455 $(#[$common_stability_attribute])*
456 impl<'a, P: Pattern<'a>> Iterator for $forward_iterator<'a, P> {
460 fn next(&mut self) -> Option<$iterty> {
465 $(#[$common_stability_attribute])*
466 impl<'a, P> Clone for $forward_iterator<'a, P>
468 P: Pattern<'a, Searcher: Clone>,
470 fn clone(&self) -> Self {
471 $forward_iterator(self.0.clone())
475 $(#[$reverse_iterator_attribute])*
476 $(#[$common_stability_attribute])*
477 pub struct $reverse_iterator<'a, P: Pattern<'a>>(pub(super) $internal_iterator<'a, P>);
479 $(#[$common_stability_attribute])*
480 impl<'a, P> fmt::Debug for $reverse_iterator<'a, P>
482 P: Pattern<'a, Searcher: fmt::Debug>,
484 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
485 f.debug_tuple(stringify!($reverse_iterator))
491 $(#[$common_stability_attribute])*
492 impl<'a, P> Iterator for $reverse_iterator<'a, P>
494 P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
499 fn next(&mut self) -> Option<$iterty> {
504 $(#[$common_stability_attribute])*
505 impl<'a, P> Clone for $reverse_iterator<'a, P>
507 P: Pattern<'a, Searcher: Clone>,
509 fn clone(&self) -> Self {
510 $reverse_iterator(self.0.clone())
514 #[stable(feature = "fused", since = "1.26.0")]
515 impl<'a, P: Pattern<'a>> FusedIterator for $forward_iterator<'a, P> {}
517 #[stable(feature = "fused", since = "1.26.0")]
518 impl<'a, P> FusedIterator for $reverse_iterator<'a, P>
520 P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
523 generate_pattern_iterators!($($t)* with $(#[$common_stability_attribute])*,
525 $reverse_iterator, $iterty);
528 double ended; with $(#[$common_stability_attribute:meta])*,
529 $forward_iterator:ident,
530 $reverse_iterator:ident, $iterty:ty
532 $(#[$common_stability_attribute])*
533 impl<'a, P> DoubleEndedIterator for $forward_iterator<'a, P>
535 P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,
538 fn next_back(&mut self) -> Option<$iterty> {
543 $(#[$common_stability_attribute])*
544 impl<'a, P> DoubleEndedIterator for $reverse_iterator<'a, P>
546 P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,
549 fn next_back(&mut self) -> Option<$iterty> {
555 single ended; with $(#[$common_stability_attribute:meta])*,
556 $forward_iterator:ident,
557 $reverse_iterator:ident, $iterty:ty
561 derive_pattern_clone! {
563 with |s| SplitInternal { matcher: s.matcher.clone(), ..*s }
566 pub(super) struct SplitInternal<'a, P: Pattern<'a>> {
567 pub(super) start: usize,
568 pub(super) end: usize,
569 pub(super) matcher: P::Searcher,
570 pub(super) allow_trailing_empty: bool,
571 pub(super) finished: bool,
574 impl<'a, P> fmt::Debug for SplitInternal<'a, P>
576 P: Pattern<'a, Searcher: fmt::Debug>,
578 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
579 f.debug_struct("SplitInternal")
580 .field("start", &self.start)
581 .field("end", &self.end)
582 .field("matcher", &self.matcher)
583 .field("allow_trailing_empty", &self.allow_trailing_empty)
584 .field("finished", &self.finished)
589 impl<'a, P: Pattern<'a>> SplitInternal<'a, P> {
591 fn get_end(&mut self) -> Option<&'a str> {
592 if !self.finished && (self.allow_trailing_empty || self.end - self.start > 0) {
593 self.finished = true;
594 // SAFETY: `self.start` and `self.end` always lie on unicode boundaries.
596 let string = self.matcher.haystack().get_unchecked(self.start..self.end);
605 fn next(&mut self) -> Option<&'a str> {
610 let haystack = self.matcher.haystack();
611 match self.matcher.next_match() {
612 // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries.
613 Some((a, b)) => unsafe {
614 let elt = haystack.get_unchecked(self.start..a);
618 None => self.get_end(),
623 fn next_inclusive(&mut self) -> Option<&'a str> {
628 let haystack = self.matcher.haystack();
629 match self.matcher.next_match() {
630 // SAFETY: `Searcher` guarantees that `b` lies on unicode boundary,
631 // and self.start is either the start of the original string,
632 // or `b` was assigned to it, so it also lies on unicode boundary.
633 Some((_, b)) => unsafe {
634 let elt = haystack.get_unchecked(self.start..b);
638 None => self.get_end(),
643 fn next_back(&mut self) -> Option<&'a str>
645 P::Searcher: ReverseSearcher<'a>,
651 if !self.allow_trailing_empty {
652 self.allow_trailing_empty = true;
653 match self.next_back() {
654 Some(elt) if !elt.is_empty() => return Some(elt),
663 let haystack = self.matcher.haystack();
664 match self.matcher.next_match_back() {
665 // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries.
666 Some((a, b)) => unsafe {
667 let elt = haystack.get_unchecked(b..self.end);
671 // SAFETY: `self.start` and `self.end` always lie on unicode boundaries.
673 self.finished = true;
674 Some(haystack.get_unchecked(self.start..self.end))
680 fn next_back_inclusive(&mut self) -> Option<&'a str>
682 P::Searcher: ReverseSearcher<'a>,
688 if !self.allow_trailing_empty {
689 self.allow_trailing_empty = true;
690 match self.next_back_inclusive() {
691 Some(elt) if !elt.is_empty() => return Some(elt),
700 let haystack = self.matcher.haystack();
701 match self.matcher.next_match_back() {
702 // SAFETY: `Searcher` guarantees that `b` lies on unicode boundary,
703 // and 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 Some((_, b)) => unsafe {
706 let elt = haystack.get_unchecked(b..self.end);
710 // SAFETY: self.start is either the start of the original string,
711 // or start of a substring that represents the part of the string that hasn't
712 // iterated yet. Either way, it is guaranteed to lie on unicode boundary.
713 // self.end is either the end of the original string,
714 // or `b` was assigned to it, so it also lies on unicode boundary.
716 self.finished = true;
717 Some(haystack.get_unchecked(self.start..self.end))
723 fn as_str(&self) -> &'a str {
724 // `Self::get_end` doesn't change `self.start`
729 // SAFETY: `self.start` and `self.end` always lie on unicode boundaries.
730 unsafe { self.matcher.haystack().get_unchecked(self.start..self.end) }
734 generate_pattern_iterators! {
736 /// Created with the method [`split`].
738 /// [`split`]: str::split
741 /// Created with the method [`rsplit`].
743 /// [`rsplit`]: str::rsplit
746 #[stable(feature = "rust1", since = "1.0.0")]
748 SplitInternal yielding (&'a str);
749 delegate double ended;
752 impl<'a, P: Pattern<'a>> Split<'a, P> {
753 /// Returns remainder of the splitted string
758 /// #![feature(str_split_as_str)]
759 /// let mut split = "Mary had a little lamb".split(' ');
760 /// assert_eq!(split.as_str(), "Mary had a little lamb");
762 /// assert_eq!(split.as_str(), "had a little lamb");
763 /// split.by_ref().for_each(drop);
764 /// assert_eq!(split.as_str(), "");
767 #[unstable(feature = "str_split_as_str", issue = "77998")]
768 pub fn as_str(&self) -> &'a str {
773 impl<'a, P: Pattern<'a>> RSplit<'a, P> {
774 /// Returns remainder of the splitted string
779 /// #![feature(str_split_as_str)]
780 /// let mut split = "Mary had a little lamb".rsplit(' ');
781 /// assert_eq!(split.as_str(), "Mary had a little lamb");
783 /// assert_eq!(split.as_str(), "Mary had a little");
784 /// split.by_ref().for_each(drop);
785 /// assert_eq!(split.as_str(), "");
788 #[unstable(feature = "str_split_as_str", issue = "77998")]
789 pub fn as_str(&self) -> &'a str {
794 generate_pattern_iterators! {
796 /// Created with the method [`split_terminator`].
798 /// [`split_terminator`]: str::split_terminator
799 struct SplitTerminator;
801 /// Created with the method [`rsplit_terminator`].
803 /// [`rsplit_terminator`]: str::rsplit_terminator
804 struct RSplitTerminator;
806 #[stable(feature = "rust1", since = "1.0.0")]
808 SplitInternal yielding (&'a str);
809 delegate double ended;
812 impl<'a, P: Pattern<'a>> SplitTerminator<'a, P> {
813 /// Returns remainder of the splitted string
818 /// #![feature(str_split_as_str)]
819 /// let mut split = "A..B..".split_terminator('.');
820 /// assert_eq!(split.as_str(), "A..B..");
822 /// assert_eq!(split.as_str(), ".B..");
823 /// split.by_ref().for_each(drop);
824 /// assert_eq!(split.as_str(), "");
827 #[unstable(feature = "str_split_as_str", issue = "77998")]
828 pub fn as_str(&self) -> &'a str {
833 impl<'a, P: Pattern<'a>> RSplitTerminator<'a, P> {
834 /// Returns remainder of the splitted string
839 /// #![feature(str_split_as_str)]
840 /// let mut split = "A..B..".rsplit_terminator('.');
841 /// assert_eq!(split.as_str(), "A..B..");
843 /// assert_eq!(split.as_str(), "A..B");
844 /// split.by_ref().for_each(drop);
845 /// assert_eq!(split.as_str(), "");
848 #[unstable(feature = "str_split_as_str", issue = "77998")]
849 pub fn as_str(&self) -> &'a str {
854 derive_pattern_clone! {
856 with |s| SplitNInternal { iter: s.iter.clone(), ..*s }
859 pub(super) struct SplitNInternal<'a, P: Pattern<'a>> {
860 pub(super) iter: SplitInternal<'a, P>,
861 /// The number of splits remaining
862 pub(super) count: usize,
865 impl<'a, P> fmt::Debug for SplitNInternal<'a, P>
867 P: Pattern<'a, Searcher: fmt::Debug>,
869 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
870 f.debug_struct("SplitNInternal")
871 .field("iter", &self.iter)
872 .field("count", &self.count)
877 impl<'a, P: Pattern<'a>> SplitNInternal<'a, P> {
879 fn next(&mut self) -> Option<&'a str> {
894 fn next_back(&mut self) -> Option<&'a str>
896 P::Searcher: ReverseSearcher<'a>,
906 self.iter.next_back()
912 fn as_str(&self) -> &'a str {
917 generate_pattern_iterators! {
919 /// Created with the method [`splitn`].
921 /// [`splitn`]: str::splitn
924 /// Created with the method [`rsplitn`].
926 /// [`rsplitn`]: str::rsplitn
929 #[stable(feature = "rust1", since = "1.0.0")]
931 SplitNInternal yielding (&'a str);
932 delegate single ended;
935 impl<'a, P: Pattern<'a>> SplitN<'a, P> {
936 /// Returns remainder of the splitted string
941 /// #![feature(str_split_as_str)]
942 /// let mut split = "Mary had a little lamb".splitn(3, ' ');
943 /// assert_eq!(split.as_str(), "Mary had a little lamb");
945 /// assert_eq!(split.as_str(), "had a little lamb");
946 /// split.by_ref().for_each(drop);
947 /// assert_eq!(split.as_str(), "");
950 #[unstable(feature = "str_split_as_str", issue = "77998")]
951 pub fn as_str(&self) -> &'a str {
956 impl<'a, P: Pattern<'a>> RSplitN<'a, P> {
957 /// Returns remainder of the splitted string
962 /// #![feature(str_split_as_str)]
963 /// let mut split = "Mary had a little lamb".rsplitn(3, ' ');
964 /// assert_eq!(split.as_str(), "Mary had a little lamb");
966 /// assert_eq!(split.as_str(), "Mary had a little");
967 /// split.by_ref().for_each(drop);
968 /// assert_eq!(split.as_str(), "");
971 #[unstable(feature = "str_split_as_str", issue = "77998")]
972 pub fn as_str(&self) -> &'a str {
977 derive_pattern_clone! {
978 clone MatchIndicesInternal
979 with |s| MatchIndicesInternal(s.0.clone())
982 pub(super) struct MatchIndicesInternal<'a, P: Pattern<'a>>(pub(super) P::Searcher);
984 impl<'a, P> fmt::Debug for MatchIndicesInternal<'a, P>
986 P: Pattern<'a, Searcher: fmt::Debug>,
988 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
989 f.debug_tuple("MatchIndicesInternal").field(&self.0).finish()
993 impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> {
995 fn next(&mut self) -> Option<(usize, &'a str)> {
998 // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
999 .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) })
1003 fn next_back(&mut self) -> Option<(usize, &'a str)>
1005 P::Searcher: ReverseSearcher<'a>,
1009 // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
1010 .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) })
1014 generate_pattern_iterators! {
1016 /// Created with the method [`match_indices`].
1018 /// [`match_indices`]: str::match_indices
1019 struct MatchIndices;
1021 /// Created with the method [`rmatch_indices`].
1023 /// [`rmatch_indices`]: str::rmatch_indices
1024 struct RMatchIndices;
1026 #[stable(feature = "str_match_indices", since = "1.5.0")]
1028 MatchIndicesInternal yielding ((usize, &'a str));
1029 delegate double ended;
1032 derive_pattern_clone! {
1033 clone MatchesInternal
1034 with |s| MatchesInternal(s.0.clone())
1037 pub(super) struct MatchesInternal<'a, P: Pattern<'a>>(pub(super) P::Searcher);
1039 impl<'a, P> fmt::Debug for MatchesInternal<'a, P>
1041 P: Pattern<'a, Searcher: fmt::Debug>,
1043 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1044 f.debug_tuple("MatchesInternal").field(&self.0).finish()
1048 impl<'a, P: Pattern<'a>> MatchesInternal<'a, P> {
1050 fn next(&mut self) -> Option<&'a str> {
1051 // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
1052 self.0.next_match().map(|(a, b)| unsafe {
1053 // Indices are known to be on utf8 boundaries
1054 self.0.haystack().get_unchecked(a..b)
1059 fn next_back(&mut self) -> Option<&'a str>
1061 P::Searcher: ReverseSearcher<'a>,
1063 // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
1064 self.0.next_match_back().map(|(a, b)| unsafe {
1065 // Indices are known to be on utf8 boundaries
1066 self.0.haystack().get_unchecked(a..b)
1071 generate_pattern_iterators! {
1073 /// Created with the method [`matches`].
1075 /// [`matches`]: str::matches
1078 /// Created with the method [`rmatches`].
1080 /// [`rmatches`]: str::rmatches
1083 #[stable(feature = "str_matches", since = "1.2.0")]
1085 MatchesInternal yielding (&'a str);
1086 delegate double ended;
1089 /// An iterator over the lines of a string, as string slices.
1091 /// This struct is created with the [`lines`] method on [`str`].
1092 /// See its documentation for more.
1094 /// [`lines`]: str::lines
1095 #[stable(feature = "rust1", since = "1.0.0")]
1096 #[must_use = "iterators are lazy and do nothing unless consumed"]
1097 #[derive(Clone, Debug)]
1098 pub struct Lines<'a>(pub(super) Map<SplitTerminator<'a, char>, LinesAnyMap>);
1100 #[stable(feature = "rust1", since = "1.0.0")]
1101 impl<'a> Iterator for Lines<'a> {
1102 type Item = &'a str;
1105 fn next(&mut self) -> Option<&'a str> {
1110 fn size_hint(&self) -> (usize, Option<usize>) {
1115 fn last(mut self) -> Option<&'a str> {
1120 #[stable(feature = "rust1", since = "1.0.0")]
1121 impl<'a> DoubleEndedIterator for Lines<'a> {
1123 fn next_back(&mut self) -> Option<&'a str> {
1128 #[stable(feature = "fused", since = "1.26.0")]
1129 impl FusedIterator for Lines<'_> {}
1131 /// Created with the method [`lines_any`].
1133 /// [`lines_any`]: str::lines_any
1134 #[stable(feature = "rust1", since = "1.0.0")]
1135 #[rustc_deprecated(since = "1.4.0", reason = "use lines()/Lines instead now")]
1136 #[must_use = "iterators are lazy and do nothing unless consumed"]
1137 #[derive(Clone, Debug)]
1138 #[allow(deprecated)]
1139 pub struct LinesAny<'a>(pub(super) Lines<'a>);
1141 #[stable(feature = "rust1", since = "1.0.0")]
1142 #[allow(deprecated)]
1143 impl<'a> Iterator for LinesAny<'a> {
1144 type Item = &'a str;
1147 fn next(&mut self) -> Option<&'a str> {
1152 fn size_hint(&self) -> (usize, Option<usize>) {
1157 #[stable(feature = "rust1", since = "1.0.0")]
1158 #[allow(deprecated)]
1159 impl<'a> DoubleEndedIterator for LinesAny<'a> {
1161 fn next_back(&mut self) -> Option<&'a str> {
1166 #[stable(feature = "fused", since = "1.26.0")]
1167 #[allow(deprecated)]
1168 impl FusedIterator for LinesAny<'_> {}
1170 /// An iterator over the non-whitespace substrings of a string,
1171 /// separated by any amount of whitespace.
1173 /// This struct is created by the [`split_whitespace`] method on [`str`].
1174 /// See its documentation for more.
1176 /// [`split_whitespace`]: str::split_whitespace
1177 #[stable(feature = "split_whitespace", since = "1.1.0")]
1178 #[derive(Clone, Debug)]
1179 pub struct SplitWhitespace<'a> {
1180 pub(super) inner: Filter<Split<'a, IsWhitespace>, IsNotEmpty>,
1183 /// An iterator over the non-ASCII-whitespace substrings of a string,
1184 /// separated by any amount of ASCII whitespace.
1186 /// This struct is created by the [`split_ascii_whitespace`] method on [`str`].
1187 /// See its documentation for more.
1189 /// [`split_ascii_whitespace`]: str::split_ascii_whitespace
1190 #[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1191 #[derive(Clone, Debug)]
1192 pub struct SplitAsciiWhitespace<'a> {
1194 Map<Filter<SliceSplit<'a, u8, IsAsciiWhitespace>, BytesIsNotEmpty>, UnsafeBytesToStr>,
1197 /// An iterator over the substrings of a string,
1198 /// terminated by a substring matching to a predicate function
1199 /// Unlike `Split`, it contains the matched part as a terminator
1200 /// of the subslice.
1202 /// This struct is created by the [`split_inclusive`] method on [`str`].
1203 /// See its documentation for more.
1205 /// [`split_inclusive`]: str::split_inclusive
1206 #[stable(feature = "split_inclusive", since = "1.51.0")]
1207 pub struct SplitInclusive<'a, P: Pattern<'a>>(pub(super) SplitInternal<'a, P>);
1209 #[stable(feature = "split_whitespace", since = "1.1.0")]
1210 impl<'a> Iterator for SplitWhitespace<'a> {
1211 type Item = &'a str;
1214 fn next(&mut self) -> Option<&'a str> {
1219 fn size_hint(&self) -> (usize, Option<usize>) {
1220 self.inner.size_hint()
1224 fn last(mut self) -> Option<&'a str> {
1229 #[stable(feature = "split_whitespace", since = "1.1.0")]
1230 impl<'a> DoubleEndedIterator for SplitWhitespace<'a> {
1232 fn next_back(&mut self) -> Option<&'a str> {
1233 self.inner.next_back()
1237 #[stable(feature = "fused", since = "1.26.0")]
1238 impl FusedIterator for SplitWhitespace<'_> {}
1240 impl<'a> SplitWhitespace<'a> {
1241 /// Returns remainder of the splitted string
1246 /// #![feature(str_split_whitespace_as_str)]
1248 /// let mut split = "Mary had a little lamb".split_whitespace();
1249 /// assert_eq!(split.as_str(), "Mary had a little lamb");
1252 /// assert_eq!(split.as_str(), "had a little lamb");
1254 /// split.by_ref().for_each(drop);
1255 /// assert_eq!(split.as_str(), "");
1259 #[unstable(feature = "str_split_whitespace_as_str", issue = "77998")]
1260 pub fn as_str(&self) -> &'a str {
1261 self.inner.iter.as_str()
1265 #[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1266 impl<'a> Iterator for SplitAsciiWhitespace<'a> {
1267 type Item = &'a str;
1270 fn next(&mut self) -> Option<&'a str> {
1275 fn size_hint(&self) -> (usize, Option<usize>) {
1276 self.inner.size_hint()
1280 fn last(mut self) -> Option<&'a str> {
1285 #[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1286 impl<'a> DoubleEndedIterator for SplitAsciiWhitespace<'a> {
1288 fn next_back(&mut self) -> Option<&'a str> {
1289 self.inner.next_back()
1293 #[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1294 impl FusedIterator for SplitAsciiWhitespace<'_> {}
1296 impl<'a> SplitAsciiWhitespace<'a> {
1297 /// Returns remainder of the splitted string
1302 /// #![feature(str_split_whitespace_as_str)]
1304 /// let mut split = "Mary had a little lamb".split_ascii_whitespace();
1305 /// assert_eq!(split.as_str(), "Mary had a little lamb");
1308 /// assert_eq!(split.as_str(), "had a little lamb");
1310 /// split.by_ref().for_each(drop);
1311 /// assert_eq!(split.as_str(), "");
1315 #[unstable(feature = "str_split_whitespace_as_str", issue = "77998")]
1316 pub fn as_str(&self) -> &'a str {
1317 if self.inner.iter.iter.finished {
1321 // SAFETY: Slice is created from str.
1322 unsafe { crate::str::from_utf8_unchecked(&self.inner.iter.iter.v) }
1326 #[stable(feature = "split_inclusive", since = "1.51.0")]
1327 impl<'a, P: Pattern<'a>> Iterator for SplitInclusive<'a, P> {
1328 type Item = &'a str;
1331 fn next(&mut self) -> Option<&'a str> {
1332 self.0.next_inclusive()
1336 #[stable(feature = "split_inclusive", since = "1.51.0")]
1337 impl<'a, P: Pattern<'a, Searcher: fmt::Debug>> fmt::Debug for SplitInclusive<'a, P> {
1338 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1339 f.debug_struct("SplitInclusive").field("0", &self.0).finish()
1343 // FIXME(#26925) Remove in favor of `#[derive(Clone)]`
1344 #[stable(feature = "split_inclusive", since = "1.51.0")]
1345 impl<'a, P: Pattern<'a, Searcher: Clone>> Clone for SplitInclusive<'a, P> {
1346 fn clone(&self) -> Self {
1347 SplitInclusive(self.0.clone())
1351 #[stable(feature = "split_inclusive", since = "1.51.0")]
1352 impl<'a, P: Pattern<'a, Searcher: ReverseSearcher<'a>>> DoubleEndedIterator
1353 for SplitInclusive<'a, P>
1356 fn next_back(&mut self) -> Option<&'a str> {
1357 self.0.next_back_inclusive()
1361 #[stable(feature = "split_inclusive", since = "1.51.0")]
1362 impl<'a, P: Pattern<'a>> FusedIterator for SplitInclusive<'a, P> {}
1364 impl<'a, P: Pattern<'a>> SplitInclusive<'a, P> {
1365 /// Returns remainder of the splitted string
1370 /// #![feature(str_split_inclusive_as_str)]
1371 /// let mut split = "Mary had a little lamb".split_inclusive(' ');
1372 /// assert_eq!(split.as_str(), "Mary had a little lamb");
1374 /// assert_eq!(split.as_str(), "had a little lamb");
1375 /// split.by_ref().for_each(drop);
1376 /// assert_eq!(split.as_str(), "");
1379 #[unstable(feature = "str_split_inclusive_as_str", issue = "77998")]
1380 pub fn as_str(&self) -> &'a str {
1385 /// An iterator of [`u16`] over the string encoded as UTF-16.
1387 /// This struct is created by the [`encode_utf16`] method on [`str`].
1388 /// See its documentation for more.
1390 /// [`encode_utf16`]: str::encode_utf16
1392 #[stable(feature = "encode_utf16", since = "1.8.0")]
1393 pub struct EncodeUtf16<'a> {
1394 pub(super) chars: Chars<'a>,
1395 pub(super) extra: u16,
1398 #[stable(feature = "collection_debug", since = "1.17.0")]
1399 impl fmt::Debug for EncodeUtf16<'_> {
1400 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1401 f.debug_struct("EncodeUtf16").finish_non_exhaustive()
1405 #[stable(feature = "encode_utf16", since = "1.8.0")]
1406 impl<'a> Iterator for EncodeUtf16<'a> {
1410 fn next(&mut self) -> Option<u16> {
1411 if self.extra != 0 {
1412 let tmp = self.extra;
1417 let mut buf = [0; 2];
1418 self.chars.next().map(|ch| {
1419 let n = ch.encode_utf16(&mut buf).len();
1421 self.extra = buf[1];
1428 fn size_hint(&self) -> (usize, Option<usize>) {
1429 let (low, high) = self.chars.size_hint();
1430 // every char gets either one u16 or two u16,
1431 // so this iterator is between 1 or 2 times as
1432 // long as the underlying iterator.
1433 (low, high.and_then(|n| n.checked_mul(2)))
1437 #[stable(feature = "fused", since = "1.26.0")]
1438 impl FusedIterator for EncodeUtf16<'_> {}
1440 /// The return type of [`str::escape_debug`].
1441 #[stable(feature = "str_escape", since = "1.34.0")]
1442 #[derive(Clone, Debug)]
1443 pub struct EscapeDebug<'a> {
1444 pub(super) inner: Chain<
1445 Flatten<option::IntoIter<char::EscapeDebug>>,
1446 FlatMap<Chars<'a>, char::EscapeDebug, CharEscapeDebugContinue>,
1450 /// The return type of [`str::escape_default`].
1451 #[stable(feature = "str_escape", since = "1.34.0")]
1452 #[derive(Clone, Debug)]
1453 pub struct EscapeDefault<'a> {
1454 pub(super) inner: FlatMap<Chars<'a>, char::EscapeDefault, CharEscapeDefault>,
1457 /// The return type of [`str::escape_unicode`].
1458 #[stable(feature = "str_escape", since = "1.34.0")]
1459 #[derive(Clone, Debug)]
1460 pub struct EscapeUnicode<'a> {
1461 pub(super) inner: FlatMap<Chars<'a>, char::EscapeUnicode, CharEscapeUnicode>,
1464 macro_rules! escape_types_impls {
1465 ($( $Name: ident ),+) => {$(
1466 #[stable(feature = "str_escape", since = "1.34.0")]
1467 impl<'a> fmt::Display for $Name<'a> {
1468 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1469 self.clone().try_for_each(|c| f.write_char(c))
1473 #[stable(feature = "str_escape", since = "1.34.0")]
1474 impl<'a> Iterator for $Name<'a> {
1478 fn next(&mut self) -> Option<char> { self.inner.next() }
1481 fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
1484 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
1485 Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Output = Acc>
1487 self.inner.try_fold(init, fold)
1491 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
1492 where Fold: FnMut(Acc, Self::Item) -> Acc,
1494 self.inner.fold(init, fold)
1498 #[stable(feature = "str_escape", since = "1.34.0")]
1499 impl<'a> FusedIterator for $Name<'a> {}
1503 escape_types_impls!(EscapeDebug, EscapeDefault, EscapeUnicode);