/rust/registry/src/index.crates.io-6f17d22bba15001f/regex-automata-0.4.7/src/dfa/start.rs
Line | Count | Source (jump to first uncovered line) |
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 { |
31 | 0 | pub(crate) fn from_bytes( |
32 | 0 | slice: &[u8], |
33 | 0 | ) -> Result<(StartKind, usize), DeserializeError> { |
34 | 0 | wire::check_slice_len(slice, size_of::<u32>(), "start kind bytes")?; |
35 | 0 | let (n, nr) = wire::try_read_u32(slice, "start kind integer")?; |
36 | 0 | match n { |
37 | 0 | 0 => Ok((StartKind::Both, nr)), |
38 | 0 | 1 => Ok((StartKind::Unanchored, nr)), |
39 | 0 | 2 => Ok((StartKind::Anchored, nr)), |
40 | 0 | _ => Err(DeserializeError::generic("unrecognized start kind")), |
41 | | } |
42 | 0 | } |
43 | | |
44 | 0 | pub(crate) fn write_to<E: Endian>( |
45 | 0 | &self, |
46 | 0 | dst: &mut [u8], |
47 | 0 | ) -> Result<usize, SerializeError> { |
48 | 0 | let nwrite = self.write_to_len(); |
49 | 0 | if dst.len() < nwrite { |
50 | 0 | return Err(SerializeError::buffer_too_small("start kind")); |
51 | 0 | } |
52 | 0 | let n = match *self { |
53 | 0 | StartKind::Both => 0, |
54 | 0 | StartKind::Unanchored => 1, |
55 | 0 | StartKind::Anchored => 2, |
56 | | }; |
57 | 0 | E::write_u32(n, dst); |
58 | 0 | Ok(nwrite) |
59 | 0 | } |
60 | | |
61 | 0 | pub(crate) fn write_to_len(&self) -> usize { |
62 | 0 | size_of::<u32>() |
63 | 0 | } |
64 | | |
65 | | #[cfg_attr(feature = "perf-inline", inline(always))] |
66 | 0 | pub(crate) fn has_unanchored(&self) -> bool { |
67 | 0 | matches!(*self, StartKind::Both | StartKind::Unanchored) |
68 | 0 | } |
69 | | |
70 | | #[cfg_attr(feature = "perf-inline", inline(always))] |
71 | 0 | pub(crate) fn has_anchored(&self) -> bool { |
72 | 0 | matches!(*self, StartKind::Both | StartKind::Anchored) |
73 | 0 | } |
74 | | } |