Skip to main content

ct_regex_internal/expr/
iter.rs

1use std::iter::FusedIterator;
2use std::marker::PhantomData;
3use std::ops::Range;
4
5use crate::expr::{CaptureFromRanges, IndexedCaptures, Regex};
6use crate::haystack::{HaystackItem, HaystackOf};
7use crate::matcher::Matcher;
8
9/// An `Iterator` over each match in the haystack, as a [`Range<usize>`](Range). See
10/// [`Regex::range_of_all_matches`].
11#[derive(#[automatically_derived]
impl<'a, I: ::core::fmt::Debug + HaystackItem, H: ::core::fmt::Debug +
    HaystackOf<'a, I>, M: ::core::fmt::Debug + Matcher<I>> ::core::fmt::Debug
    for RangeOfAllMatches<'a, I, H, M> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "RangeOfAllMatches", "hay", &self.hay, "overlapping",
            &self.overlapping, "_phantom", &&self._phantom)
    }
}Debug, #[automatically_derived]
impl<'a, I: ::core::clone::Clone + HaystackItem, H: ::core::clone::Clone +
    HaystackOf<'a, I>, M: ::core::clone::Clone + Matcher<I>>
    ::core::clone::Clone for RangeOfAllMatches<'a, I, H, M> {
    #[inline]
    fn clone(&self) -> RangeOfAllMatches<'a, I, H, M> {
        RangeOfAllMatches {
            hay: ::core::clone::Clone::clone(&self.hay),
            overlapping: ::core::clone::Clone::clone(&self.overlapping),
            _phantom: ::core::clone::Clone::clone(&self._phantom),
        }
    }
}Clone, #[automatically_derived]
impl<'a, I: ::core::hash::Hash + HaystackItem, H: ::core::hash::Hash +
    HaystackOf<'a, I>, M: ::core::hash::Hash + Matcher<I>> ::core::hash::Hash
    for RangeOfAllMatches<'a, I, H, M> {
    #[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._phantom, state)
    }
}Hash)]
12pub struct RangeOfAllMatches<'a, I: HaystackItem, H: HaystackOf<'a, I>, M: Matcher<I>> {
13    pub(crate) hay: H,
14    pub(crate) overlapping: bool,
15    pub(crate) _phantom: PhantomData<(&'a (), I, M)>,
16}
17
18impl<'a, I: HaystackItem, H: HaystackOf<'a, I>, M: Matcher<I>> RangeOfAllMatches<'a, I, H, M> {
19    pub fn new(hay: H, overlapping: bool) -> Self {
20        RangeOfAllMatches {
21            hay,
22            overlapping,
23            _phantom: PhantomData,
24        }
25    }
26}
27
28impl<'a, I, H, M> Iterator for RangeOfAllMatches<'a, I, H, M>
29where
30    I: HaystackItem,
31    H: HaystackOf<'a, I>,
32    M: Matcher<I>,
33{
34    type Item = Range<usize>;
35
36    fn next(&mut self) -> Option<Self::Item> {
37        let _ = self.hay.item()?;
38
39        let start = self.hay.index();
40
41        if let Some(state_fork) = M::all_matches(&mut self.hay).next() {
42            if self.overlapping {
43                self.hay.rollback(start).progress();
44            } else {
45                self.hay.rollback(state_fork);
46
47                // This doesn't seem to make a difference...
48                if true {
    match (&start, &state_fork) {
        (left_val, right_val) => {
            if *left_val == *right_val {
                let kind = ::core::panicking::AssertKind::Ne;
                ::core::panicking::assert_failed(kind, &*left_val,
                    &*right_val, ::core::option::Option::None);
            }
        }
    };
}debug_assert_ne!(start, state_fork)
49                // if start == state_fork {
50                //     // We've already matched at this index.
51                //     hay.progress();
52                // }
53            }
54
55            Some(start..state_fork)
56        } else {
57            self.hay.rollback(start).progress();
58            self.next()
59        }
60    }
61}
62
63impl<'a, I, H, M> FusedIterator for RangeOfAllMatches<'a, I, H, M>
64where
65    I: HaystackItem,
66    H: HaystackOf<'a, I>,
67    M: Matcher<I>,
68{}
69
70/// An `Iterator` over each match in the haystack, as an `H::Slice`. See
71/// [`Regex::slice_all_matches`].
72#[derive(#[automatically_derived]
impl<'a, I: ::core::fmt::Debug + HaystackItem, H: ::core::fmt::Debug +
    HaystackOf<'a, I>, M: ::core::fmt::Debug + Matcher<I>> ::core::fmt::Debug
    for SliceAllMatches<'a, I, H, M> {
    #[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, I: ::core::clone::Clone + HaystackItem, H: ::core::clone::Clone +
    HaystackOf<'a, I>, M: ::core::clone::Clone + Matcher<I>>
    ::core::clone::Clone for SliceAllMatches<'a, I, H, M> {
    #[inline]
    fn clone(&self) -> SliceAllMatches<'a, I, H, M> {
        SliceAllMatches { inner: ::core::clone::Clone::clone(&self.inner) }
    }
}Clone, #[automatically_derived]
impl<'a, I: ::core::hash::Hash + HaystackItem, H: ::core::hash::Hash +
    HaystackOf<'a, I>, M: ::core::hash::Hash + Matcher<I>> ::core::hash::Hash
    for SliceAllMatches<'a, I, H, M> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.inner, state)
    }
}Hash)]
73pub struct SliceAllMatches<'a, I: HaystackItem, H: HaystackOf<'a, I>, M: Matcher<I>> {
74    pub(crate) inner: RangeOfAllMatches<'a, I, H, M>,
75}
76
77impl<'a, I, H, M> Iterator for SliceAllMatches<'a, I, H, M>
78where
79    I: HaystackItem,
80    H: HaystackOf<'a, I>,
81    M: Matcher<I>,
82{
83    type Item = H::Slice;
84
85    fn next(&mut self) -> Option<Self::Item> {
86        let range = self.inner.next()?;
87        Some(self.inner.hay.slice_with(range))
88    }
89}
90
91impl<'a, I, H, M> FusedIterator for SliceAllMatches<'a, I, H, M>
92where
93    I: HaystackItem,
94    H: HaystackOf<'a, I>,
95    M: Matcher<I>,
96{}
97
98/// An `Iterator` over each capture in the haystack, as an `R::Capture`. See
99/// [`Regex::find_all_captures`].
100#[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_field3_finish(f,
            "FindAllCaptures", "hay", &self.hay, "overlapping",
            &self.overlapping, "_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),
            _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._phantom, state)
    }
}Hash)]
101pub struct FindAllCaptures<'a, R, I, H, const N: usize>
102where
103    R: Regex<I, N> + ?Sized,
104    I: HaystackItem,
105    H: HaystackOf<'a, I>,
106{
107    pub(crate) hay: H,
108    pub(crate) overlapping: bool,
109    pub(crate) _phantom: PhantomData<(&'a (), I, R)>,
110}
111
112impl<'a, R, I, H, const N: usize> FindAllCaptures<'a, R, I, H, N>
113where
114    R: Regex<I, N> + ?Sized,
115    I: HaystackItem,
116    H: HaystackOf<'a, I>,
117{
118    pub fn new(hay: H, overlapping: bool) -> Self {
119        Self {
120            hay,
121            overlapping,
122            _phantom: PhantomData,
123        }
124    }
125}
126
127impl<'a, R, I, H, const N: usize> Iterator for FindAllCaptures<'a, R, I, H, N>
128where
129    R: Regex<I, N> + ?Sized,
130    I: HaystackItem + 'a,
131    H: HaystackOf<'a, I>,
132{
133    type Item = R::Capture<'a, H::Slice>;
134
135    fn next(&mut self) -> Option<Self::Item> {
136        let _ = self.hay.item()?;
137
138        let start = self.hay.index();
139
140        let mut caps = IndexedCaptures::default();
141
142        let first = R::Pattern::all_captures(&mut self.hay, &mut caps).next();
143
144        if let Some((state_fork, mut caps_fork)) = first {
145            caps_fork.push(0, start..state_fork);
146
147            if self.overlapping {
148                self.hay.rollback(start).progress();
149            } else {
150                self.hay.rollback(state_fork);
151                if true {
    match (&start, &state_fork) {
        (left_val, right_val) => {
            if *left_val == *right_val {
                let kind = ::core::panicking::AssertKind::Ne;
                ::core::panicking::assert_failed(kind, &*left_val,
                    &*right_val, ::core::option::Option::None);
            }
        }
    };
};debug_assert_ne!(start, state_fork);
152            }
153
154            Some(
155                R::Capture::from_ranges(caps_fork.into_array(), self.hay.inner_slice())
156                    .expect("failed to convert captures despite matching correctly")
157            )
158        } else {
159            self.hay.rollback(start).progress();
160            self.next()
161        }
162    }
163}
164
165impl<'a, R, I, H, const N: usize> FusedIterator for FindAllCaptures<'a, R, I, H, N>
166where
167    R: Regex<I, N> + ?Sized,
168    I: HaystackItem + 'a,
169    H: HaystackOf<'a, I>,
170{}