1use std::iter::FusedIterator;
2use std::marker::PhantomData;
3use std::ops::Range;
4
5use crate::anchor::Anchor;
6use crate::expr::{IndexedCaptures, FromRanges, Regex};
7use crate::haystack::{HaystackItem, HaystackOf};
8use crate::matcher::Matcher;
9
10#[derive(#[automatically_derived]
impl<'a, R: ::core::fmt::Debug, I: ::core::fmt::Debug, H: ::core::fmt::Debug,
const N : usize> ::core::fmt::Debug for RangeOfAllMatches<'a, R, I, H, N>
where R: Regex<I, N> + ?Sized, I: HaystackItem, H: HaystackOf<'a, I> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field4_finish(f,
"RangeOfAllMatches", "hay", &self.hay, "overlapping",
&self.overlapping, "last_check", &self.last_check, "_phantom",
&&self._phantom)
}
}Debug, #[automatically_derived]
impl<'a, R: ::core::clone::Clone, I: ::core::clone::Clone,
H: ::core::clone::Clone, const N : usize> ::core::clone::Clone for
RangeOfAllMatches<'a, R, I, H, N> where R: Regex<I, N> + ?Sized,
I: HaystackItem, H: HaystackOf<'a, I> {
#[inline]
fn clone(&self) -> RangeOfAllMatches<'a, R, I, H, N> {
RangeOfAllMatches {
hay: ::core::clone::Clone::clone(&self.hay),
overlapping: ::core::clone::Clone::clone(&self.overlapping),
last_check: ::core::clone::Clone::clone(&self.last_check),
_phantom: ::core::clone::Clone::clone(&self._phantom),
}
}
}Clone, #[automatically_derived]
impl<'a, R: ::core::hash::Hash, I: ::core::hash::Hash, H: ::core::hash::Hash,
const N : usize> ::core::hash::Hash for RangeOfAllMatches<'a, R, I, H, N>
where R: Regex<I, N> + ?Sized, I: HaystackItem, H: HaystackOf<'a, I> {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.hay, state);
::core::hash::Hash::hash(&self.overlapping, state);
::core::hash::Hash::hash(&self.last_check, state);
::core::hash::Hash::hash(&self._phantom, state)
}
}Hash)]
13pub struct RangeOfAllMatches<'a, R, I, H, const N: usize>
14where
15 R: Regex<I, N> + ?Sized,
16 I: HaystackItem,
17 H: HaystackOf<'a, I>,
18{
19 pub(crate) hay: H,
20 pub(crate) overlapping: bool,
21 pub(crate) last_check: bool,
22 pub(crate) _phantom: PhantomData<(&'a (), I, R)>,
23}
24
25impl<'a, R, I, H, const N: usize> RangeOfAllMatches<'a, R, I, H, N>
26where
27 R: Regex<I, N> + ?Sized,
28 I: HaystackItem,
29 H: HaystackOf<'a, I>,
30{
31 pub fn new(hay: H, overlapping: bool) -> Self {
32 RangeOfAllMatches {
33 hay,
34 overlapping,
35 last_check: false,
36 _phantom: PhantomData,
37 }
38 }
39}
40
41impl<'a, R, I, H, const N: usize> Iterator for RangeOfAllMatches<'a, R, I, H, N>
42where
43 R: Regex<I, N> + ?Sized,
44 I: HaystackItem,
45 H: HaystackOf<'a, I>,
46{
47 type Item = Range<usize>;
48
49 fn next(&mut self) -> Option<Self::Item> {
50 if self.last_check {
51 return None;
52 }
53
54 self.last_check = self.hay.item().is_none();
55 let mut ret = None;
56
57 if R::Anchors::assert(&self.hay).continue_value()? {
58 let start = self.hay.index();
59
60 if let Some(state_fork) = R::Pattern::all_matches(&mut self.hay).next() {
61 ret = Some(start..state_fork);
62
63 if !self.overlapping && start != state_fork {
67 self.hay.rollback(state_fork);
68 return ret.or_else(|| self.next());
69 }
70 }
71
72 self.hay.rollback(start);
73 }
74
75 self.hay.progress();
76 ret.or_else(|| self.next())
77 }
78}
79
80impl<'a, R, I, H, const N: usize> FusedIterator for RangeOfAllMatches<'a, R, I, H, N>
81where
82 R: Regex<I, N> + ?Sized,
83 I: HaystackItem,
84 H: HaystackOf<'a, I>,
85{}
86
87#[derive(#[automatically_derived]
impl<'a, R: ::core::fmt::Debug, I: ::core::fmt::Debug, H: ::core::fmt::Debug,
const N : usize> ::core::fmt::Debug for SliceAllMatches<'a, R, I, H, N>
where R: Regex<I, N> + ?Sized, I: HaystackItem, H: HaystackOf<'a, I> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"SliceAllMatches", "inner", &&self.inner)
}
}Debug, #[automatically_derived]
impl<'a, R: ::core::clone::Clone, I: ::core::clone::Clone,
H: ::core::clone::Clone, const N : usize> ::core::clone::Clone for
SliceAllMatches<'a, R, I, H, N> where R: Regex<I, N> + ?Sized,
I: HaystackItem, H: HaystackOf<'a, I> {
#[inline]
fn clone(&self) -> SliceAllMatches<'a, R, I, H, N> {
SliceAllMatches { inner: ::core::clone::Clone::clone(&self.inner) }
}
}Clone, #[automatically_derived]
impl<'a, R: ::core::hash::Hash, I: ::core::hash::Hash, H: ::core::hash::Hash,
const N : usize> ::core::hash::Hash for SliceAllMatches<'a, R, I, H, N>
where R: Regex<I, N> + ?Sized, I: HaystackItem, H: HaystackOf<'a, I> {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.inner, state)
}
}Hash)]
90pub struct SliceAllMatches<'a, R, I, H, const N: usize>
91where
92 R: Regex<I, N> + ?Sized,
93 I: HaystackItem,
94 H: HaystackOf<'a, I>,
95{
96 pub(crate) inner: RangeOfAllMatches<'a, R, I, H, N>,
97}
98
99impl<'a, R, I, H, const N: usize> Iterator for SliceAllMatches<'a, R, I, H, N>
100where
101 R: Regex<I, N> + ?Sized,
102 I: HaystackItem,
103 H: HaystackOf<'a, I>,
104{
105 type Item = H::Slice;
106
107 fn next(&mut self) -> Option<Self::Item> {
108 let range = self.inner.next()?;
109 Some(self.inner.hay.slice_with(range))
110 }
111}
112
113impl<'a, R, I, H, const N: usize> FusedIterator for SliceAllMatches<'a, R, I, H, N>
114where
115 R: Regex<I, N> + ?Sized,
116 I: HaystackItem,
117 H: HaystackOf<'a, I>,
118{}
119
120#[derive(#[automatically_derived]
impl<'a, R: ::core::fmt::Debug, I: ::core::fmt::Debug, H: ::core::fmt::Debug,
const N : usize> ::core::fmt::Debug for FindAllCaptures<'a, R, I, H, N>
where R: Regex<I, N> + ?Sized, I: HaystackItem, H: HaystackOf<'a, I> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field4_finish(f,
"FindAllCaptures", "hay", &self.hay, "overlapping",
&self.overlapping, "last_check", &self.last_check, "_phantom",
&&self._phantom)
}
}Debug, #[automatically_derived]
impl<'a, R: ::core::clone::Clone, I: ::core::clone::Clone,
H: ::core::clone::Clone, const N : usize> ::core::clone::Clone for
FindAllCaptures<'a, R, I, H, N> where R: Regex<I, N> + ?Sized,
I: HaystackItem, H: HaystackOf<'a, I> {
#[inline]
fn clone(&self) -> FindAllCaptures<'a, R, I, H, N> {
FindAllCaptures {
hay: ::core::clone::Clone::clone(&self.hay),
overlapping: ::core::clone::Clone::clone(&self.overlapping),
last_check: ::core::clone::Clone::clone(&self.last_check),
_phantom: ::core::clone::Clone::clone(&self._phantom),
}
}
}Clone, #[automatically_derived]
impl<'a, R: ::core::hash::Hash, I: ::core::hash::Hash, H: ::core::hash::Hash,
const N : usize> ::core::hash::Hash for FindAllCaptures<'a, R, I, H, N>
where R: Regex<I, N> + ?Sized, I: HaystackItem, H: HaystackOf<'a, I> {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.hay, state);
::core::hash::Hash::hash(&self.overlapping, state);
::core::hash::Hash::hash(&self.last_check, state);
::core::hash::Hash::hash(&self._phantom, state)
}
}Hash)]
123pub struct FindAllCaptures<'a, R, I, H, const N: usize>
124where
125 R: Regex<I, N> + ?Sized,
126 I: HaystackItem,
127 H: HaystackOf<'a, I>,
128{
129 pub(crate) hay: H,
130 pub(crate) overlapping: bool,
131 pub(crate) last_check: bool,
132 pub(crate) _phantom: PhantomData<(&'a (), I, R)>,
133}
134
135impl<'a, R, I, H, const N: usize> FindAllCaptures<'a, R, I, H, N>
136where
137 R: Regex<I, N> + ?Sized,
138 I: HaystackItem,
139 H: HaystackOf<'a, I>,
140{
141 pub fn new(hay: H, overlapping: bool) -> Self {
142 Self {
143 hay,
144 overlapping,
145 last_check: false,
146 _phantom: PhantomData,
147 }
148 }
149}
150
151impl<'a, R, I, H, const N: usize> Iterator for FindAllCaptures<'a, R, I, H, N>
152where
153 R: Regex<I, N> + ?Sized,
154 I: HaystackItem + 'a,
155 H: HaystackOf<'a, I>,
156{
157 type Item = R::Capture<'a, H::Slice>;
158
159 fn next(&mut self) -> Option<Self::Item> {
160 if self.last_check {
161 return None;
162 }
163
164 self.last_check = self.hay.item().is_none();
165 let mut ret = None;
166
167 if R::Anchors::assert(&self.hay).continue_value()? {
168 let start = self.hay.index();
169 let mut caps = IndexedCaptures::default();
170
171 if let Some((
172 state_fork,
173 mut caps_fork
174 )) = R::Pattern::all_captures(&mut self.hay, &mut caps).next() {
175 caps_fork.push(0, start..state_fork);
176 ret = Some(
177 R::Capture::from_ranges(caps_fork.into_array(), self.hay.inner_slice())
178 .expect("failed to convert captures despite matching correctly")
179 );
180
181 if !self.overlapping && start != state_fork {
185 self.hay.rollback(state_fork);
186 return ret.or_else(|| self.next());
187 }
188 }
189
190 self.hay.rollback(start);
191 }
192
193 self.hay.progress();
194 ret.or_else(|| self.next())
195 }
196}
197
198impl<'a, R, I, H, const N: usize> FusedIterator for FindAllCaptures<'a, R, I, H, N>
199where
200 R: Regex<I, N> + ?Sized,
201 I: HaystackItem + 'a,
202 H: HaystackOf<'a, I>,
203{}