1use crate::util::{
2 prefilter::PrefilterI,
3 search::{MatchKind, Span},
4};
5
6#[derive(Clone, Debug)]
7pub(crate) struct ByteSet([bool; 256]);
8
9impl ByteSet {
10 pub(crate) fn new<B: AsRef<[u8]>>(
11 _kind: MatchKind,
12 needles: &[B],
13 ) -> Option<ByteSet> {
14 #[cfg(not(feature = "perf-literal-multisubstring"))]
15 {
16 None
17 }
18 #[cfg(feature = "perf-literal-multisubstring")]
19 {
20 let mut set: [bool; 256] = [false; 256];
21 for needle: &B in needles.iter() {
22 let needle: &[u8] = needle.as_ref();
23 if needle.len() != 1 {
24 return None;
25 }
26 set[usize::from(needle[0])] = true;
27 }
28 Some(ByteSet(set))
29 }
30 }
31}
32
33impl PrefilterI for ByteSet {
34 fn find(&self, haystack: &[u8], span: Span) -> Option<Span> {
35 haystack[span].iter().position(|&b| self.0[usize::from(b)]).map(|i| {
36 let start = span.start + i;
37 let end = start + 1;
38 Span { start, end }
39 })
40 }
41
42 fn prefix(&self, haystack: &[u8], span: Span) -> Option<Span> {
43 let b = *haystack.get(span.start)?;
44 if self.0[usize::from(b)] {
45 Some(Span { start: span.start, end: span.start + 1 })
46 } else {
47 None
48 }
49 }
50
51 fn memory_usage(&self) -> usize {
52 0
53 }
54
55 fn is_fast(&self) -> bool {
56 false
57 }
58}
59