use core::mem::size_of; use crate::util::wire::{self, DeserializeError, Endian, SerializeError}; /// The kind of anchored starting configurations to support in a DFA. /// /// Fully compiled DFAs need to be explicitly configured as to which anchored /// starting configurations to support. The reason for not just supporting /// everything unconditionally is that it can use more resources (such as /// memory and build time). The downside of this is that if you try to execute /// a search using an [`Anchored`](crate::Anchored) mode that is not supported /// by the DFA, then the search will return an error. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum StartKind { /// Support both anchored and unanchored searches. Both, /// Support only unanchored searches. Requesting an anchored search will /// panic. /// /// Note that even if an unanchored search is requested, the pattern itself /// may still be anchored. For example, `^abc` will only match `abc` at the /// start of a haystack. This will remain true, even if the regex engine /// only supported unanchored searches. Unanchored, /// Support only anchored searches. Requesting an unanchored search will /// panic. Anchored, } impl StartKind { pub(crate) fn from_bytes( slice: &[u8], ) -> Result<(StartKind, usize), DeserializeError> { wire::check_slice_len(slice, size_of::(), "start kind bytes")?; let (n, nr) = wire::try_read_u32(slice, "start kind integer")?; match n { 0 => Ok((StartKind::Both, nr)), 1 => Ok((StartKind::Unanchored, nr)), 2 => Ok((StartKind::Anchored, nr)), _ => Err(DeserializeError::generic("unrecognized start kind")), } } pub(crate) fn write_to( &self, dst: &mut [u8], ) -> Result { let nwrite = self.write_to_len(); if dst.len() < nwrite { return Err(SerializeError::buffer_too_small("start kind")); } let n = match *self { StartKind::Both => 0, StartKind::Unanchored => 1, StartKind::Anchored => 2, }; E::write_u32(n, dst); Ok(nwrite) } pub(crate) fn write_to_len(&self) -> usize { size_of::() } #[cfg_attr(feature = "perf-inline", inline(always))] pub(crate) fn has_unanchored(&self) -> bool { matches!(*self, StartKind::Both | StartKind::Unanchored) } #[cfg_attr(feature = "perf-inline", inline(always))] pub(crate) fn has_anchored(&self) -> bool { matches!(*self, StartKind::Both | StartKind::Anchored) } }