regex_automata/util/prefilter/
memmem.rs1use crate::util::{
2 prefilter::PrefilterI,
3 search::{MatchKind, Span},
4};
5
6#[derive(Clone, Debug)]
7pub(crate) struct Memmem {
8 #[cfg(not(all(feature = "std", feature = "perf-literal-substring")))]
9 _unused: (),
10 #[cfg(all(feature = "std", feature = "perf-literal-substring"))]
11 finder: memchr::memmem::Finder<'static>,
12}
13
14impl Memmem {
15 pub(crate) fn new<B: AsRef<[u8]>>(
16 _kind: MatchKind,
17 needles: &[B],
18 ) -> Option<Memmem> {
19 #[cfg(not(all(feature = "std", feature = "perf-literal-substring")))]
20 {
21 None
22 }
23 #[cfg(all(feature = "std", feature = "perf-literal-substring"))]
24 {
25 if needles.len() != 1 {
26 return None;
27 }
28 let needle = needles[0].as_ref();
29 let finder = memchr::memmem::Finder::new(needle).into_owned();
30 Some(Memmem { finder })
31 }
32 }
33}
34
35impl PrefilterI for Memmem {
36 fn name(&self) -> &'static str {
37 "memmem"
38 }
39
40 fn find(&self, haystack: &[u8], span: Span) -> Option<Span> {
41 #[cfg(not(all(feature = "std", feature = "perf-literal-substring")))]
42 {
43 unreachable!()
44 }
45 #[cfg(all(feature = "std", feature = "perf-literal-substring"))]
46 {
47 self.finder.find(&haystack[span]).map(|i| {
48 let start = span.start + i;
49 let end = start + self.finder.needle().len();
50 Span { start, end }
51 })
52 }
53 }
54
55 fn prefix(&self, haystack: &[u8], span: Span) -> Option<Span> {
56 #[cfg(not(all(feature = "std", feature = "perf-literal-substring")))]
57 {
58 unreachable!()
59 }
60 #[cfg(all(feature = "std", feature = "perf-literal-substring"))]
61 {
62 let needle = self.finder.needle();
63 if haystack[span].starts_with(needle) {
64 Some(Span { end: span.start + needle.len(), ..span })
65 } else {
66 None
67 }
68 }
69 }
70
71 fn memory_usage(&self) -> usize {
72 #[cfg(not(all(feature = "std", feature = "perf-literal-substring")))]
73 {
74 unreachable!()
75 }
76 #[cfg(all(feature = "std", feature = "perf-literal-substring"))]
77 {
78 self.finder.needle().len()
79 }
80 }
81
82 fn is_fast(&self) -> bool {
83 #[cfg(not(all(feature = "std", feature = "perf-literal-substring")))]
84 {
85 unreachable!()
86 }
87 #[cfg(all(feature = "std", feature = "perf-literal-substring"))]
88 {
89 true
90 }
91 }
92}