summaryrefslogtreecommitdiffstats
path: root/third_party/rust/regex-automata/src/dfa/start.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/regex-automata/src/dfa/start.rs')
-rw-r--r--third_party/rust/regex-automata/src/dfa/start.rs74
1 files changed, 74 insertions, 0 deletions
diff --git a/third_party/rust/regex-automata/src/dfa/start.rs b/third_party/rust/regex-automata/src/dfa/start.rs
new file mode 100644
index 0000000000..fddc702df5
--- /dev/null
+++ b/third_party/rust/regex-automata/src/dfa/start.rs
@@ -0,0 +1,74 @@
+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::<u32>(), "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<E: Endian>(
+ &self,
+ dst: &mut [u8],
+ ) -> Result<usize, SerializeError> {
+ 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::<u32>()
+ }
+
+ #[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)
+ }
+}