1use 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: &[u8] = needles[0].as_ref();
29 let finder: Finder<'_> = memchr::memmem::Finder::new(needle).into_owned();
30 Some(Memmem { finder })
31 }
32 }
33}
34
35impl PrefilterI for Memmem {
36 fn find(&self, haystack: &[u8], span: Span) -> Option<Span> {
37 #[cfg(not(all(feature = "std", feature = "perf-literal-substring")))]
38 {
39 unreachable!()
40 }
41 #[cfg(all(feature = "std", feature = "perf-literal-substring"))]
42 {
43 self.finder.find(&haystack[span]).map(|i| {
44 let start = span.start + i;
45 let end = start + self.finder.needle().len();
46 Span { start, end }
47 })
48 }
49 }
50
51 fn prefix(&self, haystack: &[u8], span: Span) -> Option<Span> {
52 #[cfg(not(all(feature = "std", feature = "perf-literal-substring")))]
53 {
54 unreachable!()
55 }
56 #[cfg(all(feature = "std", feature = "perf-literal-substring"))]
57 {
58 let needle = self.finder.needle();
59 if haystack[span].starts_with(needle) {
60 Some(Span { end: span.start + needle.len(), ..span })
61 } else {
62 None
63 }
64 }
65 }
66
67 fn memory_usage(&self) -> usize {
68 #[cfg(not(all(feature = "std", feature = "perf-literal-substring")))]
69 {
70 unreachable!()
71 }
72 #[cfg(all(feature = "std", feature = "perf-literal-substring"))]
73 {
74 self.finder.needle().len()
75 }
76 }
77
78 fn is_fast(&self) -> bool {
79 #[cfg(not(all(feature = "std", feature = "perf-literal-substring")))]
80 {
81 unreachable!()
82 }
83 #[cfg(all(feature = "std", feature = "perf-literal-substring"))]
84 {
85 true
86 }
87 }
88}
89