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