regex_automata/util/prefilter/
byteset.rs

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 = [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 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}