1use core::fmt;
4use core::iter::FusedIterator;
5
6
7use super::pattern::Pattern;
8use super::pattern::{DoubleEndedSearcher, ReverseSearcher, Searcher};
9
10macro_rules! derive_pattern_clone {
13 (clone $t:ident with |$s:ident| $e:expr) => {
14 impl<'a, P> Clone for $t<'a, P>
15 where
16 P: Pattern<'a>, <P as Pattern<'a>>::Searcher: Clone
17 {
18 fn clone(&self) -> Self {
19 let $s = self;
20 $e
21 }
22 }
23 };
24}
25
26macro_rules! generate_pattern_iterators {
65 {
66 forward:
68 $(#[$forward_iterator_attribute:meta])*
69 struct $forward_iterator:ident;
70
71 reverse:
73 $(#[$reverse_iterator_attribute:meta])*
74 struct $reverse_iterator:ident;
75
76 internal:
78 $internal_iterator:ident yielding ($iterty:ty);
79
80 delegate $($t:tt)*
82 } => {
83 $(#[$forward_iterator_attribute])*
84 pub struct $forward_iterator<'a, P: Pattern<'a>>(pub $internal_iterator<'a, P>);
85
86 impl<'a, P> fmt::Debug for $forward_iterator<'a, P>
87 where
88 P: Pattern<'a>, <P as Pattern<'a>>::Searcher: fmt::Debug,
89 {
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91 f.debug_tuple(stringify!($forward_iterator))
92 .field(&self.0)
93 .finish()
94 }
95 }
96
97 impl<'a, P: Pattern<'a>> Iterator for $forward_iterator<'a, P> {
98 type Item = $iterty;
99
100 #[inline]
101 fn next(&mut self) -> Option<$iterty> {
102 self.0.next()
103 }
104 }
105
106 impl<'a, P> Clone for $forward_iterator<'a, P>
107 where
108 P: Pattern<'a>, <P as Pattern<'a>>::Searcher: Clone,
109 {
110 fn clone(&self) -> Self {
111 $forward_iterator(self.0.clone())
112 }
113 }
114
115 $(#[$reverse_iterator_attribute])*
116 pub struct $reverse_iterator<'a, P: Pattern<'a>>(pub $internal_iterator<'a, P>);
117
118 impl<'a, P> fmt::Debug for $reverse_iterator<'a, P>
119 where
120 P: Pattern<'a>, <P as Pattern<'a>>::Searcher: fmt::Debug,
121 {
122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123 f.debug_tuple(stringify!($reverse_iterator))
124 .field(&self.0)
125 .finish()
126 }
127 }
128
129 impl<'a, P> Iterator for $reverse_iterator<'a, P>
130 where
131 P: Pattern<'a>, <P as Pattern<'a>>::Searcher: ReverseSearcher<'a>,
132 {
133 type Item = $iterty;
134
135 #[inline]
136 fn next(&mut self) -> Option<$iterty> {
137 self.0.next_back()
138 }
139 }
140
141 impl<'a, P> Clone for $reverse_iterator<'a, P>
142 where
143 P: Pattern<'a>, <P as Pattern<'a>>::Searcher: Clone,
144 {
145 fn clone(&self) -> Self {
146 $reverse_iterator(self.0.clone())
147 }
148 }
149
150 impl<'a, P: Pattern<'a>> FusedIterator for $forward_iterator<'a, P> {}
151
152 impl<'a, P> FusedIterator for $reverse_iterator<'a, P>
153 where
154 P: Pattern<'a>, <P as Pattern<'a>>::Searcher: ReverseSearcher<'a>,
155 {}
156
157 generate_pattern_iterators!($($t)* with $forward_iterator, $reverse_iterator, $iterty);
158 };
159 {
160 double ended; with $forward_iterator:ident,
161 $reverse_iterator:ident, $iterty:ty
162 } => {
163 impl<'a, P> DoubleEndedIterator for $forward_iterator<'a, P>
164 where
165 P: Pattern<'a>, <P as Pattern<'a>>::Searcher: DoubleEndedSearcher<'a>,
166 {
167 #[inline]
168 fn next_back(&mut self) -> Option<$iterty> {
169 self.0.next_back()
170 }
171 }
172
173 impl<'a, P> DoubleEndedIterator for $reverse_iterator<'a, P>
174 where
175 P: Pattern<'a>, <P as Pattern<'a>>::Searcher: DoubleEndedSearcher<'a>,
176 {
177 #[inline]
178 fn next_back(&mut self) -> Option<$iterty> {
179 self.0.next()
180 }
181 }
182 };
183 {
184 single ended; with $forward_iterator:ident,
185 $reverse_iterator:ident, $iterty:ty
186 } => {}
187}
188
189derive_pattern_clone! {
190 clone SplitInternal
191 with |s| SplitInternal { matcher: s.matcher.clone(), ..*s }
192}
193
194pub struct SplitInternal<'a, P: Pattern<'a>> {
195 pub start: usize,
196 pub end: usize,
197 pub matcher: P::Searcher,
198 pub allow_trailing_empty: bool,
199 pub finished: bool,
200}
201
202impl<'a, P> fmt::Debug for SplitInternal<'a, P>
203where
204 P: Pattern<'a>, <P as Pattern<'a>>::Searcher: fmt::Debug,
205{
206 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207 f.debug_struct("SplitInternal")
208 .field("start", &self.start)
209 .field("end", &self.end)
210 .field("matcher", &self.matcher)
211 .field("allow_trailing_empty", &self.allow_trailing_empty)
212 .field("finished", &self.finished)
213 .finish()
214 }
215}
216
217impl<'a, P: Pattern<'a>> SplitInternal<'a, P> {
218 #[inline]
219 fn get_end(&mut self) -> Option<&'a str> {
220 if !self.finished && (self.allow_trailing_empty || self.end - self.start > 0) {
221 self.finished = true;
222 unsafe {
224 let string = self.matcher.haystack().get_unchecked(self.start..self.end);
225 Some(string)
226 }
227 } else {
228 None
229 }
230 }
231
232 #[inline]
233 fn next(&mut self) -> Option<&'a str> {
234 if self.finished {
235 return None;
236 }
237
238 let haystack = self.matcher.haystack();
239 match self.matcher.next_match() {
240 Some((a, b)) => unsafe {
242 let elt = haystack.get_unchecked(self.start..a);
243 self.start = b;
244 Some(elt)
245 },
246 None => self.get_end(),
247 }
248 }
249
250 #[inline]
251 #[allow(dead_code)]
252 fn next_inclusive(&mut self) -> Option<&'a str> {
253 if self.finished {
254 return None;
255 }
256
257 let haystack = self.matcher.haystack();
258 match self.matcher.next_match() {
259 Some((_, b)) => unsafe {
263 let elt = haystack.get_unchecked(self.start..b);
264 self.start = b;
265 Some(elt)
266 },
267 None => self.get_end(),
268 }
269 }
270
271 #[inline]
272 fn next_back(&mut self) -> Option<&'a str>
273 where
274 P::Searcher: ReverseSearcher<'a>,
275 {
276 if self.finished {
277 return None;
278 }
279
280 if !self.allow_trailing_empty {
281 self.allow_trailing_empty = true;
282 match self.next_back() {
283 Some(elt) if !elt.is_empty() => return Some(elt),
284 _ => {
285 if self.finished {
286 return None;
287 }
288 }
289 }
290 }
291
292 let haystack = self.matcher.haystack();
293 match self.matcher.next_match_back() {
294 Some((a, b)) => unsafe {
296 let elt = haystack.get_unchecked(b..self.end);
297 self.end = a;
298 Some(elt)
299 },
300 None => unsafe {
302 self.finished = true;
303 Some(haystack.get_unchecked(self.start..self.end))
304 },
305 }
306 }
307
308 #[inline]
309 #[allow(dead_code)]
310 fn next_back_inclusive(&mut self) -> Option<&'a str>
311 where
312 P::Searcher: ReverseSearcher<'a>,
313 {
314 if self.finished {
315 return None;
316 }
317
318 if !self.allow_trailing_empty {
319 self.allow_trailing_empty = true;
320 match self.next_back_inclusive() {
321 Some(elt) if !elt.is_empty() => return Some(elt),
322 _ => {
323 if self.finished {
324 return None;
325 }
326 }
327 }
328 }
329
330 let haystack = self.matcher.haystack();
331 match self.matcher.next_match_back() {
332 Some((_, b)) => unsafe {
336 let elt = haystack.get_unchecked(b..self.end);
337 self.end = b;
338 Some(elt)
339 },
340 None => unsafe {
346 self.finished = true;
347 Some(haystack.get_unchecked(self.start..self.end))
348 },
349 }
350 }
351
352 #[inline]
353 fn as_str(&self) -> &'a str {
354 if self.finished {
356 return "";
357 }
358
359 unsafe { self.matcher.haystack().get_unchecked(self.start..self.end) }
361 }
362}
363
364generate_pattern_iterators! {
365 forward:
366 struct Split;
370 reverse:
371 struct RSplit;
375 internal:
376 SplitInternal yielding (&'a str);
377 delegate double ended;
378}
379
380impl<'a, P: Pattern<'a>> Split<'a, P> {
381 #[inline]
394 pub fn as_str(&self) -> &'a str {
395 self.0.as_str()
396 }
397}
398
399impl<'a, P: Pattern<'a>> RSplit<'a, P> {
400 #[inline]
413 pub fn as_str(&self) -> &'a str {
414 self.0.as_str()
415 }
416}
417
418generate_pattern_iterators! {
419 forward:
420 struct SplitTerminator;
424 reverse:
425 struct RSplitTerminator;
429 internal:
430 SplitInternal yielding (&'a str);
431 delegate double ended;
432}
433
434impl<'a, P: Pattern<'a>> SplitTerminator<'a, P> {
435 #[inline]
448 pub fn as_str(&self) -> &'a str {
449 self.0.as_str()
450 }
451}
452
453impl<'a, P: Pattern<'a>> RSplitTerminator<'a, P> {
454 #[inline]
467 pub fn as_str(&self) -> &'a str {
468 self.0.as_str()
469 }
470}
471
472derive_pattern_clone! {
473 clone SplitNInternal
474 with |s| SplitNInternal { iter: s.iter.clone(), ..*s }
475}
476
477pub struct SplitNInternal<'a, P: Pattern<'a>> {
478 pub iter: SplitInternal<'a, P>,
479 pub count: usize,
481}
482
483impl<'a, P> fmt::Debug for SplitNInternal<'a, P>
484where
485 P: Pattern<'a>, <P as Pattern<'a>>::Searcher: fmt::Debug,
486{
487 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
488 f.debug_struct("SplitNInternal")
489 .field("iter", &self.iter)
490 .field("count", &self.count)
491 .finish()
492 }
493}
494
495impl<'a, P: Pattern<'a>> SplitNInternal<'a, P> {
496 #[inline]
497 fn next(&mut self) -> Option<&'a str> {
498 match self.count {
499 0 => None,
500 1 => {
501 self.count = 0;
502 self.iter.get_end()
503 }
504 _ => {
505 self.count -= 1;
506 self.iter.next()
507 }
508 }
509 }
510
511 #[inline]
512 fn next_back(&mut self) -> Option<&'a str>
513 where
514 P::Searcher: ReverseSearcher<'a>,
515 {
516 match self.count {
517 0 => None,
518 1 => {
519 self.count = 0;
520 self.iter.get_end()
521 }
522 _ => {
523 self.count -= 1;
524 self.iter.next_back()
525 }
526 }
527 }
528
529 #[inline]
530 fn as_str(&self) -> &'a str {
531 self.iter.as_str()
532 }
533}
534
535generate_pattern_iterators! {
536 forward:
537 struct SplitN;
541 reverse:
542 struct RSplitN;
546 internal:
547 SplitNInternal yielding (&'a str);
548 delegate single ended;
549}
550
551impl<'a, P: Pattern<'a>> SplitN<'a, P> {
552 #[inline]
565 pub fn as_str(&self) -> &'a str {
566 self.0.as_str()
567 }
568}
569
570impl<'a, P: Pattern<'a>> RSplitN<'a, P> {
571 #[inline]
584 pub fn as_str(&self) -> &'a str {
585 self.0.as_str()
586 }
587}
588
589derive_pattern_clone! {
590 clone MatchIndicesInternal
591 with |s| MatchIndicesInternal(s.0.clone())
592}
593
594pub struct MatchIndicesInternal<'a, P: Pattern<'a>>(pub P::Searcher);
595
596impl<'a, P> fmt::Debug for MatchIndicesInternal<'a, P>
597where
598 P: Pattern<'a>, <P as Pattern<'a>>::Searcher: fmt::Debug,
599{
600 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
601 f.debug_tuple("MatchIndicesInternal").field(&self.0).finish()
602 }
603}
604
605impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> {
606 #[inline]
607 fn next(&mut self) -> Option<(usize, &'a str)> {
608 self.0
609 .next_match()
610 .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) })
612 }
613
614 #[inline]
615 fn next_back(&mut self) -> Option<(usize, &'a str)>
616 where
617 P::Searcher: ReverseSearcher<'a>,
618 {
619 self.0
620 .next_match_back()
621 .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) })
623 }
624}
625
626generate_pattern_iterators! {
627 forward:
628 struct MatchIndices;
632 reverse:
633 struct RMatchIndices;
637 internal:
638 MatchIndicesInternal yielding ((usize, &'a str));
639 delegate double ended;
640}
641
642derive_pattern_clone! {
643 clone MatchesInternal
644 with |s| MatchesInternal(s.0.clone())
645}
646
647pub struct MatchesInternal<'a, P: Pattern<'a>>(pub P::Searcher);
648
649impl<'a, P> fmt::Debug for MatchesInternal<'a, P>
650where
651 P: Pattern<'a>, <P as Pattern<'a>>::Searcher: fmt::Debug,
652{
653 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
654 f.debug_tuple("MatchesInternal").field(&self.0).finish()
655 }
656}
657
658impl<'a, P: Pattern<'a>> MatchesInternal<'a, P> {
659 #[inline]
660 fn next(&mut self) -> Option<&'a str> {
661 self.0.next_match().map(|(a, b)| unsafe {
663 self.0.haystack().get_unchecked(a..b)
665 })
666 }
667
668 #[inline]
669 fn next_back(&mut self) -> Option<&'a str>
670 where
671 P::Searcher: ReverseSearcher<'a>,
672 {
673 self.0.next_match_back().map(|(a, b)| unsafe {
675 self.0.haystack().get_unchecked(a..b)
677 })
678 }
679}
680
681generate_pattern_iterators! {
682 forward:
683 struct Matches;
687 reverse:
688 struct RMatches;
692 internal:
693 MatchesInternal yielding (&'a str);
694 delegate double ended;
695}