Skip to main content

ct_regex_internal/matcher/
lazy.rs

1use std::fmt::{self, Debug};
2use std::iter::{self, FusedIterator};
3use std::marker::PhantomData;
4
5use crate::expr::IndexedCaptures;
6use crate::haystack::{HaystackItem, HaystackOf};
7use crate::matcher::{
8    AllCapturesSingle, AllMatchesSingle, LazyMatcher, Matcher, QuantifierNOrMore, QuantifierNToM,
9};
10
11#[derive(#[automatically_derived]
impl<I: ::core::default::Default + HaystackItem, Q: ::core::default::Default +
    LazyMatcher<I>> ::core::default::Default for Lazy<I, Q> {
    #[inline]
    fn default() -> Lazy<I, Q> {
        Lazy(::core::default::Default::default(),
            ::core::default::Default::default())
    }
}Default, #[automatically_derived]
impl<I: ::core::clone::Clone + HaystackItem, Q: ::core::clone::Clone +
    LazyMatcher<I>> ::core::clone::Clone for Lazy<I, Q> {
    #[inline]
    fn clone(&self) -> Lazy<I, Q> {
        Lazy(::core::clone::Clone::clone(&self.0),
            ::core::clone::Clone::clone(&self.1))
    }
}Clone, #[automatically_derived]
impl<I: ::core::marker::Copy + HaystackItem, Q: ::core::marker::Copy +
    LazyMatcher<I>> ::core::marker::Copy for Lazy<I, Q> {
}Copy)]
12pub struct Lazy<I: HaystackItem, Q: LazyMatcher<I>>(pub PhantomData<I>, pub PhantomData<Q>);
13
14impl<I: HaystackItem, Q: LazyMatcher<I>> Matcher<I> for Lazy<I, Q> {
15    type AllMatches<'a, H: HaystackOf<'a, I>> = Q::LazyAllMatches<'a, H>;
16    type AllCaptures<'a, H: HaystackOf<'a, I>> = Q::LazyAllCaptures<'a, H>;
17
18    fn matches<'a, H: HaystackOf<'a, I>>(hay: &mut H) -> bool {
19        Q::lazy_matches(hay)
20    }
21
22    fn all_matches<'a, H: HaystackOf<'a, I>>(hay: &mut H) -> Self::AllMatches<'a, H> {
23        Q::lazy_all_matches(hay)
24    }
25
26    fn captures<'a, H: HaystackOf<'a, I>>(hay: &mut H, caps: &mut IndexedCaptures) -> bool {
27        Q::lazy_captures(hay, caps)
28    }
29
30    fn all_captures<'a, H: HaystackOf<'a, I>>(
31        hay: &mut H,
32        caps: &mut IndexedCaptures,
33    ) -> Self::AllCaptures<'a, H> {
34        Q::lazy_all_captures(hay, caps)
35    }
36}
37
38impl<I: HaystackItem, Q: LazyMatcher<I>> Debug for Lazy<I, Q> {
39    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40        f.write_fmt(format_args!("{0:?}?", Q::default()))write!(f, "{:?}?", Q::default())
41    }
42}
43
44#[derive(#[automatically_derived]
impl<'a, I: ::core::fmt::Debug, H: ::core::fmt::Debug, A: ::core::fmt::Debug,
    const N : usize> ::core::fmt::Debug for
    LazyAllMatchesNOrMore<'a, I, H, A, N> where I: HaystackItem,
    H: HaystackOf<'a, I>, A: Matcher<I> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "LazyAllMatchesNOrMore", "hay", &self.hay, "count", &self.count,
            "_phantom", &&self._phantom)
    }
}Debug, #[automatically_derived]
impl<'a, I: ::core::clone::Clone, H: ::core::clone::Clone,
    A: ::core::clone::Clone, const N : usize> ::core::clone::Clone for
    LazyAllMatchesNOrMore<'a, I, H, A, N> where I: HaystackItem,
    H: HaystackOf<'a, I>, A: Matcher<I> {
    #[inline]
    fn clone(&self) -> LazyAllMatchesNOrMore<'a, I, H, A, N> {
        LazyAllMatchesNOrMore {
            hay: ::core::clone::Clone::clone(&self.hay),
            count: ::core::clone::Clone::clone(&self.count),
            _phantom: ::core::clone::Clone::clone(&self._phantom),
        }
    }
}Clone, #[automatically_derived]
impl<'a, I: ::core::hash::Hash, H: ::core::hash::Hash, A: ::core::hash::Hash,
    const N : usize> ::core::hash::Hash for
    LazyAllMatchesNOrMore<'a, I, H, A, N> where I: HaystackItem,
    H: HaystackOf<'a, I>, A: Matcher<I> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.hay, state);
        ::core::hash::Hash::hash(&self.count, state);
        ::core::hash::Hash::hash(&self._phantom, state)
    }
}Hash)]
45pub struct LazyAllMatchesNOrMore<'a, I, H, A, const N: usize>
46where
47    I: HaystackItem,
48    H: HaystackOf<'a, I>,
49    A: Matcher<I>,
50{
51    hay: H,
52    count: usize,
53    _phantom: PhantomData<(&'a (), I, A)>,
54}
55
56impl<'a, I, H, A, const N: usize> Iterator for LazyAllMatchesNOrMore<'a, I, H, A, N>
57where
58    I: HaystackItem,
59    H: HaystackOf<'a, I>,
60    A: Matcher<I>,
61{
62    type Item = usize;
63
64    fn next(&mut self) -> Option<Self::Item> {
65        // N == 0 is handled before we create an Iterator.
66        if A::matches(&mut self.hay) {
67            self.count += 1;
68            if self.count >= N {
69                Some(self.hay.index())
70            } else {
71                self.next()
72            }
73        } else {
74            None
75        }
76    }
77}
78
79impl<'a, I, H, A, const N: usize> FusedIterator for LazyAllMatchesNOrMore<'a, I, H, A, N>
80where
81    I: HaystackItem,
82    H: HaystackOf<'a, I>,
83    A: Matcher<I>,
84{}
85
86#[derive(#[automatically_derived]
impl<'a, I: ::core::fmt::Debug, H: ::core::fmt::Debug, A: ::core::fmt::Debug,
    const N : usize> ::core::fmt::Debug for
    LazyAllCapturesNOrMore<'a, I, H, A, N> where I: HaystackItem,
    H: HaystackOf<'a, I>, A: Matcher<I> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field4_finish(f,
            "LazyAllCapturesNOrMore", "hay", &self.hay, "caps", &self.caps,
            "count", &self.count, "_phantom", &&self._phantom)
    }
}Debug, #[automatically_derived]
impl<'a, I: ::core::clone::Clone, H: ::core::clone::Clone,
    A: ::core::clone::Clone, const N : usize> ::core::clone::Clone for
    LazyAllCapturesNOrMore<'a, I, H, A, N> where I: HaystackItem,
    H: HaystackOf<'a, I>, A: Matcher<I> {
    #[inline]
    fn clone(&self) -> LazyAllCapturesNOrMore<'a, I, H, A, N> {
        LazyAllCapturesNOrMore {
            hay: ::core::clone::Clone::clone(&self.hay),
            caps: ::core::clone::Clone::clone(&self.caps),
            count: ::core::clone::Clone::clone(&self.count),
            _phantom: ::core::clone::Clone::clone(&self._phantom),
        }
    }
}Clone, #[automatically_derived]
impl<'a, I: ::core::hash::Hash, H: ::core::hash::Hash, A: ::core::hash::Hash,
    const N : usize> ::core::hash::Hash for
    LazyAllCapturesNOrMore<'a, I, H, A, N> where I: HaystackItem,
    H: HaystackOf<'a, I>, A: Matcher<I> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.hay, state);
        ::core::hash::Hash::hash(&self.caps, state);
        ::core::hash::Hash::hash(&self.count, state);
        ::core::hash::Hash::hash(&self._phantom, state)
    }
}Hash)]
87pub struct LazyAllCapturesNOrMore<'a, I, H, A, const N: usize>
88where
89    I: HaystackItem,
90    H: HaystackOf<'a, I>,
91    A: Matcher<I>,
92{
93    hay: H,
94    caps: IndexedCaptures,
95    count: usize,
96    _phantom: PhantomData<(&'a (), I, A)>,
97}
98
99impl<'a, I, H, A, const N: usize> Iterator for LazyAllCapturesNOrMore<'a, I, H, A, N>
100where
101    I: HaystackItem,
102    H: HaystackOf<'a, I>,
103    A: Matcher<I>,
104{
105    type Item = (usize, IndexedCaptures);
106
107    fn next(&mut self) -> Option<Self::Item> {
108        if A::captures(&mut self.hay, &mut self.caps) {
109            self.count += 1;
110            if self.count >= N {
111                Some((self.hay.index(), self.caps.clone()))
112            } else {
113                self.next()
114            }
115        } else {
116            None
117        }
118    }
119}
120
121impl<'a, I, H, A, const N: usize> FusedIterator for LazyAllCapturesNOrMore<'a, I, H, A, N>
122where
123    I: HaystackItem,
124    H: HaystackOf<'a, I>,
125    A: Matcher<I>,
126{}
127
128impl<I: HaystackItem, A: Matcher<I>, const N: usize> LazyMatcher<I> for QuantifierNOrMore<I, A, N> {
129    type LazyAllMatches<'a, H: HaystackOf<'a, I>> = iter::Chain<AllMatchesSingle, LazyAllMatchesNOrMore<'a, I, H, A, N>>;
130    type LazyAllCaptures<'a, H: HaystackOf<'a, I>> = iter::Chain<AllCapturesSingle, LazyAllCapturesNOrMore<'a, I, H, A, N>>;
131
132    fn lazy_matches<'a, H: HaystackOf<'a, I>>(hay: &mut H) -> bool {
133        let mut count = 0;
134        loop {
135            if count >= N {
136                return true;
137            }
138            if A::matches(hay) {
139                count += 1;
140            } else {
141                break;
142            }
143        }
144        false
145    }
146
147    fn lazy_all_matches<'a, H: HaystackOf<'a, I>>(hay: &mut H) -> Self::LazyAllMatches<'a, H> {
148        let zero_match = if N == 0 {
149            Some(hay.index())
150        } else {
151            None
152        };
153
154        zero_match.into_iter().chain(
155            LazyAllMatchesNOrMore {
156                hay: hay.clone(),
157                count: 0,
158                _phantom: PhantomData,
159            }
160        )
161    }
162
163    fn lazy_captures<'a, H: HaystackOf<'a, I>>(hay: &mut H, caps: &mut IndexedCaptures) -> bool {
164        let mut count = 0;
165        loop {
166            if count >= N {
167                return true;
168            }
169            if A::captures(hay, caps) {
170                count += 1;
171            } else {
172                break;
173            }
174        }
175        false
176    }
177
178    fn lazy_all_captures<'a, H: HaystackOf<'a, I>>(
179        hay: &mut H,
180        caps: &mut IndexedCaptures,
181    ) -> Self::LazyAllCaptures<'a, H> {
182        let zero_match = if N == 0 {
183            Some((hay.index(), caps.clone()))
184        } else {
185            None
186        };
187
188        zero_match.into_iter().chain(
189            LazyAllCapturesNOrMore {
190                hay: hay.clone(),
191                caps: caps.clone(),
192                count: 0,
193                _phantom: PhantomData,
194            }
195        )
196    }
197}
198
199pub struct LazyAllMatchesNToM<'a, I, H, A, const N: usize, const M: usize>
200where
201    I: HaystackItem,
202    H: HaystackOf<'a, I>,
203    A: Matcher<I>,
204{
205    hay: H,
206    count: usize,
207    _phantom: PhantomData<(&'a (), I, A)>,
208}
209
210impl<'a, I, H, A, const N: usize, const M: usize> Iterator for LazyAllMatchesNToM<'a, I, H, A, N, M>
211where
212    I: HaystackItem,
213    H: HaystackOf<'a, I>,
214    A: Matcher<I>,
215{
216    type Item = usize;
217
218    fn next(&mut self) -> Option<Self::Item> {
219        if A::matches(&mut self.hay) {
220            self.count += 1;
221            if N <= self.count && self.count <= M {
222                Some(self.hay.index())
223            } else {
224                self.next()
225            }
226        } else {
227            None
228        }
229    }
230}
231
232pub struct LazyAllCapturesNToM<'a, I, H, A, const N: usize, const M: usize>
233where
234    I: HaystackItem,
235    H: HaystackOf<'a, I>,
236    A: Matcher<I>,
237{
238    hay: H,
239    caps: IndexedCaptures,
240    count: usize,
241    _phantom: PhantomData<(&'a (), I, A)>,
242}
243
244impl<'a, I, H, A, const N: usize, const M: usize> Iterator for LazyAllCapturesNToM<'a, I, H, A, N, M>
245where
246    I: HaystackItem,
247    H: HaystackOf<'a, I>,
248    A: Matcher<I>,
249{
250    type Item = (usize, IndexedCaptures);
251
252    fn next(&mut self) -> Option<Self::Item> {
253        if A::captures(&mut self.hay, &mut self.caps) {
254            self.count += 1;
255            if N <= self.count && self.count <= M {
256                Some((self.hay.index(), self.caps.clone()))
257            } else {
258                self.next()
259            }
260        } else {
261            None
262        }
263    }
264}
265
266impl<I: HaystackItem, A: Matcher<I>, const N: usize, const M: usize> LazyMatcher<I> for QuantifierNToM<I, A, N, M> {
267    type LazyAllMatches<'a, H: HaystackOf<'a, I>> = iter::Chain<AllMatchesSingle, LazyAllMatchesNToM<'a, I, H, A, N, M>>;
268    type LazyAllCaptures<'a, H: HaystackOf<'a, I>> = iter::Chain<AllCapturesSingle, LazyAllCapturesNToM<'a, I, H, A, N, M>>;
269
270    fn lazy_matches<'a, H: HaystackOf<'a, I>>(hay: &mut H) -> bool {
271        let mut count = 0;
272        loop {
273            if count >= N && count <= M {
274                return true;
275            }
276            if A::matches(hay) {
277                count += 1;
278            } else {
279                break;
280            }
281        }
282        false
283    }
284
285    fn lazy_all_matches<'a, H: HaystackOf<'a, I>>(hay: &mut H) -> Self::LazyAllMatches<'a, H> {
286        let zero_match = if N == 0 {
287            Some(hay.index())
288        } else {
289            None
290        };
291
292        zero_match.into_iter().chain(
293            LazyAllMatchesNToM {
294                hay: hay.clone(),
295                count: 0,
296                _phantom: PhantomData,
297            }
298        )
299    }
300
301    fn lazy_captures<'a, H: HaystackOf<'a, I>>(hay: &mut H, caps: &mut IndexedCaptures) -> bool {
302        let mut count = 0;
303        loop {
304            if count >= N && count <= M {
305                return true;
306            }
307            if A::captures(hay, caps) {
308                count += 1;
309            } else {
310                break;
311            }
312        }
313        false
314    }
315
316    fn lazy_all_captures<'a, H: HaystackOf<'a, I>>(
317        hay: &mut H,
318        caps: &mut IndexedCaptures,
319    ) -> Self::LazyAllCaptures<'a, H> {
320        let zero_match = if N == 0 {
321            Some((hay.index(), caps.clone()))
322        } else {
323            None
324        };
325
326        zero_match.into_iter().chain(
327            LazyAllCapturesNToM {
328                hay: hay.clone(),
329                caps: caps.clone(),
330                count: 0,
331                _phantom: PhantomData,
332            }
333        )
334    }
335}