use core::str::pattern::{Pattern, Searcher, SearchStep};
/// A transparent wrapper for a closure or function,used for implement Pattern on it,needed due to the orphan rule.
///
/// This is only expanded with the feature `pattern_pred_support` enabled.
#[repr(transparent)]
pub struct Closure<F: FnMut(FixedStrNZ$len) -> bool> {
pub f: F,
}
/// This is only expanded with the feature `pattern_pred_support` enabled.
impl<F: FnMut(FixedStrNZ$len) -> bool> From<F> for Closure<F> {
fn from(f: F) -> Self {
Self { f }
}
}
/// This is only expanded with the feature `pattern_pred_support` enabled.
impl<'a, F: FnMut(FixedStrNZ$len) -> bool> Pattern<'a> for Closure<F> {
type Searcher = FixedStrNZ$lenPredicateSearcher<'a, F>;
fn into_searcher(self, haystack: &'a str) -> Self::Searcher {
FixedStrNZ$lenPredicateSearcher {
pattern: self,
start: 0,
end: 0,
haystack,
}
}
}
/// A Searcher that takes as pattern a predicate which takes FixedStrNZ$len.
///
/// As FixedStrNZ$len not allows bytes with zeroes and those are not stripped in the
/// [`Deref`](struct.FixedStrNZ$len.html#impl-Deref) and [`PartialEq`](struct.FixedStrNZ$len.html#impl-PartialEq) implementation
/// therefore this searcher searchs upon subslices with length *$len*,skipping some
/// bytes when the haystack length is not a multiple of $len.
///
/// This is only expanded with the feature `pattern_pred_support` enabled.
pub struct FixedStrNZ$lenPredicateSearcher<'a, F: FnMut(FixedStrNZ$len) -> bool> {
pattern: Closure<F>,
haystack: &'a str,
start: usize,
end: usize,
}
/// This is only expanded with the feature `pattern_pred_support` enabled.
unsafe impl<'a, F: FnMut(FixedStrNZ$len) -> bool> Searcher<'a> for FixedStrNZ$lenPredicateSearcher<'a, F> {
#[inline]
fn haystack(&self) -> &'a str {
&self.haystack
}
#[inline]
fn next(&mut self) -> SearchStep {
if self.start == self.haystack().len() {
return SearchStep::Done
}
let pat = unsafe {
let temp = &self.haystack[self.start..];
if temp.len() >= $len {
FixedStrNZ$len::from_str_unchecked(temp.get_unchecked(..$len))
} else {
return SearchStep::Done
}
};
self.end += $len;
let start_s = self.start;
self.start = self.end;
if unsafe { core::mem::transmute_copy::<Closure<F>, F>(&self.pattern) }(pat) {
SearchStep::Match(start_s, self.end)
} else {
SearchStep::Reject(start_s, self.end)
}
} // sample of this logic
// hay: "aaaabbb", $len 4, pattern: |s| s == "aaaa",
// Match(0, 4)
// Done
}