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