1 use core::mem::size_of;
2 
3 use crate::util::wire::{self, DeserializeError, Endian, SerializeError};
4 
5 /// The kind of anchored starting configurations to support in a DFA.
6 ///
7 /// Fully compiled DFAs need to be explicitly configured as to which anchored
8 /// starting configurations to support. The reason for not just supporting
9 /// everything unconditionally is that it can use more resources (such as
10 /// memory and build time). The downside of this is that if you try to execute
11 /// a search using an [`Anchored`](crate::Anchored) mode that is not supported
12 /// by the DFA, then the search will return an error.
13 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
14 pub enum StartKind {
15     /// Support both anchored and unanchored searches.
16     Both,
17     /// Support only unanchored searches. Requesting an anchored search will
18     /// panic.
19     ///
20     /// Note that even if an unanchored search is requested, the pattern itself
21     /// may still be anchored. For example, `^abc` will only match `abc` at the
22     /// start of a haystack. This will remain true, even if the regex engine
23     /// only supported unanchored searches.
24     Unanchored,
25     /// Support only anchored searches. Requesting an unanchored search will
26     /// panic.
27     Anchored,
28 }
29 
30 impl StartKind {
from_bytes( slice: &[u8], ) -> Result<(StartKind, usize), DeserializeError>31     pub(crate) fn from_bytes(
32         slice: &[u8],
33     ) -> Result<(StartKind, usize), DeserializeError> {
34         wire::check_slice_len(slice, size_of::<u32>(), "start kind bytes")?;
35         let (n, nr) = wire::try_read_u32(slice, "start kind integer")?;
36         match n {
37             0 => Ok((StartKind::Both, nr)),
38             1 => Ok((StartKind::Unanchored, nr)),
39             2 => Ok((StartKind::Anchored, nr)),
40             _ => Err(DeserializeError::generic("unrecognized start kind")),
41         }
42     }
43 
write_to<E: Endian>( &self, dst: &mut [u8], ) -> Result<usize, SerializeError>44     pub(crate) fn write_to<E: Endian>(
45         &self,
46         dst: &mut [u8],
47     ) -> Result<usize, SerializeError> {
48         let nwrite = self.write_to_len();
49         if dst.len() < nwrite {
50             return Err(SerializeError::buffer_too_small("start kind"));
51         }
52         let n = match *self {
53             StartKind::Both => 0,
54             StartKind::Unanchored => 1,
55             StartKind::Anchored => 2,
56         };
57         E::write_u32(n, dst);
58         Ok(nwrite)
59     }
60 
write_to_len(&self) -> usize61     pub(crate) fn write_to_len(&self) -> usize {
62         size_of::<u32>()
63     }
64 
65     #[cfg_attr(feature = "perf-inline", inline(always))]
has_unanchored(&self) -> bool66     pub(crate) fn has_unanchored(&self) -> bool {
67         matches!(*self, StartKind::Both | StartKind::Unanchored)
68     }
69 
70     #[cfg_attr(feature = "perf-inline", inline(always))]
has_anchored(&self) -> bool71     pub(crate) fn has_anchored(&self) -> bool {
72         matches!(*self, StartKind::Both | StartKind::Anchored)
73     }
74 }
75