regex_automata/util/prefilter/
byteset.rs1use 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 = [false; 256];
21 for needle in needles.iter() {
22 let needle = 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 name(&self) -> &'static str {
35 "byteset"
36 }
37
38 fn find(&self, haystack: &[u8], span: Span) -> Option<Span> {
39 haystack[span].iter().position(|&b| self.0[usize::from(b)]).map(|i| {
40 let start = span.start + i;
41 let end = start + 1;
42 Span { start, end }
43 })
44 }
45
46 fn prefix(&self, haystack: &[u8], span: Span) -> Option<Span> {
47 let b = *haystack.get(span.start)?;
48 if self.0[usize::from(b)] {
49 Some(Span { start: span.start, end: span.start + 1 })
50 } else {
51 None
52 }
53 }
54
55 fn memory_usage(&self) -> usize {
56 0
57 }
58
59 fn is_fast(&self) -> bool {
60 false
61 }
62}