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