diff options
Diffstat (limited to 'crates/matcher/src')
-rw-r--r-- | crates/matcher/src/lib.rs | 185 |
1 files changed, 179 insertions, 6 deletions
diff --git a/crates/matcher/src/lib.rs b/crates/matcher/src/lib.rs index 2bcd0c12..4859de39 100644 --- a/crates/matcher/src/lib.rs +++ b/crates/matcher/src/lib.rs @@ -618,12 +618,31 @@ pub trait Matcher { fn find_iter<F>( &self, haystack: &[u8], + matched: F, + ) -> Result<(), Self::Error> + where + F: FnMut(Match) -> bool, + { + self.find_iter_at(haystack, 0, matched) + } + + /// Executes the given function over successive non-overlapping matches + /// in `haystack`. If no match exists, then the given function is never + /// called. If the function returns `false`, then iteration stops. + /// + /// The significance of the starting point is that it takes the surrounding + /// context into consideration. For example, the `\A` anchor can only + /// match when `at == 0`. + fn find_iter_at<F>( + &self, + haystack: &[u8], + at: usize, mut matched: F, ) -> Result<(), Self::Error> where F: FnMut(Match) -> bool, { - self.try_find_iter(haystack, |m| Ok(matched(m))) + self.try_find_iter_at(haystack, at, |m| Ok(matched(m))) .map(|r: Result<(), ()>| r.unwrap()) } @@ -637,12 +656,35 @@ pub trait Matcher { fn try_find_iter<F, E>( &self, haystack: &[u8], + matched: F, + ) -> Result<Result<(), E>, Self::Error> + where + F: FnMut(Match) -> Result<bool, E>, + { + self.try_find_iter_at(haystack, 0, matched) + } + + /// Executes the given function over successive non-overlapping matches + /// in `haystack`. If no match exists, then the given function is never + /// called. If the function returns `false`, then iteration stops. + /// Similarly, if the function returns an error then iteration stops and + /// the error is yielded. If an error occurs while executing the search, + /// then it is converted to + /// `E`. + /// + /// The significance of the starting point is that it takes the surrounding + /// context into consideration. For example, the `\A` anchor can only + /// match when `at == 0`. + fn try_find_iter_at<F, E>( + &self, + haystack: &[u8], + at: usize, mut matched: F, ) -> Result<Result<(), E>, Self::Error> where F: FnMut(Match) -> Result<bool, E>, { - let mut last_end = 0; + let mut last_end = at; let mut last_match = None; loop { @@ -696,12 +738,33 @@ pub trait Matcher { &self, haystack: &[u8], caps: &mut Self::Captures, + matched: F, + ) -> Result<(), Self::Error> + where + F: FnMut(&Self::Captures) -> bool, + { + self.captures_iter_at(haystack, 0, caps, matched) + } + + /// Executes the given function over successive non-overlapping matches + /// in `haystack` with capture groups extracted from each match. If no + /// match exists, then the given function is never called. If the function + /// returns `false`, then iteration stops. + /// + /// The significance of the starting point is that it takes the surrounding + /// context into consideration. For example, the `\A` anchor can only + /// match when `at == 0`. + fn captures_iter_at<F>( + &self, + haystack: &[u8], + at: usize, + caps: &mut Self::Captures, mut matched: F, ) -> Result<(), Self::Error> where F: FnMut(&Self::Captures) -> bool, { - self.try_captures_iter(haystack, caps, |caps| Ok(matched(caps))) + self.try_captures_iter_at(haystack, at, caps, |caps| Ok(matched(caps))) .map(|r: Result<(), ()>| r.unwrap()) } @@ -716,12 +779,36 @@ pub trait Matcher { &self, haystack: &[u8], caps: &mut Self::Captures, + matched: F, + ) -> Result<Result<(), E>, Self::Error> + where + F: FnMut(&Self::Captures) -> Result<bool, E>, + { + self.try_captures_iter_at(haystack, 0, caps, matched) + } + + /// Executes the given function over successive non-overlapping matches + /// in `haystack` with capture groups extracted from each match. If no + /// match exists, then the given function is never called. If the function + /// returns `false`, then iteration stops. Similarly, if the function + /// returns an error then iteration stops and the error is yielded. If + /// an error occurs while executing the search, then it is converted to + /// `E`. + /// + /// The significance of the starting point is that it takes the surrounding + /// context into consideration. For example, the `\A` anchor can only + /// match when `at == 0`. + fn try_captures_iter_at<F, E>( + &self, + haystack: &[u8], + at: usize, + caps: &mut Self::Captures, mut matched: F, ) -> Result<Result<(), E>, Self::Error> where F: FnMut(&Self::Captures) -> Result<bool, E>, { - let mut last_end = 0; + let mut last_end = at; let mut last_match = None; loop { @@ -819,13 +906,35 @@ pub trait Matcher { haystack: &[u8], caps: &mut Self::Captures, dst: &mut Vec<u8>, + append: F, + ) -> Result<(), Self::Error> + where + F: FnMut(&Self::Captures, &mut Vec<u8>) -> bool, + { + self.replace_with_captures_at(haystack, 0, caps, dst, append) + } + + /// Replaces every match in the given haystack with the result of calling + /// `append` with the matching capture groups. + /// + /// If the given `append` function returns `false`, then replacement stops. + /// + /// The significance of the starting point is that it takes the surrounding + /// context into consideration. For example, the `\A` anchor can only + /// match when `at == 0`. + fn replace_with_captures_at<F>( + &self, + haystack: &[u8], + at: usize, + caps: &mut Self::Captures, + dst: &mut Vec<u8>, mut append: F, ) -> Result<(), Self::Error> where F: FnMut(&Self::Captures, &mut Vec<u8>) -> bool, { - let mut last_match = 0; - self.captures_iter(haystack, caps, |caps| { + let mut last_match = at; + self.captures_iter_at(haystack, at, caps, |caps| { let m = caps.get(0).unwrap(); dst.extend(&haystack[last_match..m.start]); last_match = m.end; @@ -1039,6 +1148,18 @@ impl<'a, M: Matcher> Matcher for &'a M { (*self).find_iter(haystack, matched) } + fn find_iter_at<F>( + &self, + haystack: &[u8], + at: usize, + matched: F, + ) -> Result<(), Self::Error> + where + F: FnMut(Match) -> bool, + { + (*self).find_iter_at(haystack, at, matched) + } + fn try_find_iter<F, E>( &self, haystack: &[u8], @@ -1050,6 +1171,18 @@ impl<'a, M: Matcher> Matcher for &'a M { (*self).try_find_iter(haystack, matched) } + fn try_find_iter_at<F, E>( + &self, + haystack: &[u8], + at: usize, + matched: F, + ) -> Result<Result<(), E>, Self::Error> + where + F: FnMut(Match) -> Result<bool, E>, + { + (*self).try_find_iter_at(haystack, at, matched) + } + fn captures( &self, haystack: &[u8], @@ -1070,6 +1203,19 @@ impl<'a, M: Matcher> Matcher for &'a M { (*self).captures_iter(haystack, caps, matched) } + fn captures_iter_at<F>( + &self, + haystack: &[u8], + at: usize, + caps: &mut Self::Captures, + matched: F, + ) -> Result<(), Self::Error> + where + F: FnMut(&Self::Captures) -> bool, + { + (*self).captures_iter_at(haystack, at, caps, matched) + } + fn try_captures_iter<F, E>( &self, haystack: &[u8], @@ -1082,6 +1228,19 @@ impl<'a, M: Matcher> Matcher for &'a M { (*self).try_captures_iter(haystack, caps, matched) } + fn try_captures_iter_at<F, E>( + &self, + haystack: &[u8], + at: usize, + caps: &mut Self::Captures, + matched: F, + ) -> Result<Result<(), E>, Self::Error> + where + F: FnMut(&Self::Captures) -> Result<bool, E>, + { + (*self).try_captures_iter_at(haystack, at, caps, matched) + } + fn replace<F>( &self, haystack: &[u8], @@ -1107,6 +1266,20 @@ impl<'a, M: Matcher> Matcher for &'a M { (*self).replace_with_captures(haystack, caps, dst, append) } + fn replace_with_captures_at<F>( + &self, + haystack: &[u8], + at: usize, + caps: &mut Self::Captures, + dst: &mut Vec<u8>, + append: F, + ) -> Result<(), Self::Error> + where + F: FnMut(&Self::Captures, &mut Vec<u8>) -> bool, + { + (*self).replace_with_captures_at(haystack, at, caps, dst, append) + } + fn is_match(&self, haystack: &[u8]) -> Result<bool, Self::Error> { (*self).is_match(haystack) } |