1use crate::util::{
2captures, look,
3 primitives::{PatternID, StateID},
4};
56/// An error that can occurred during the construction of a thompson NFA.
7///
8/// This error does not provide many introspection capabilities. There are
9/// generally only two things you can do with it:
10///
11/// * Obtain a human readable message via its `std::fmt::Display` impl.
12/// * Access an underlying [`regex_syntax::Error`] type from its `source`
13/// method via the `std::error::Error` trait. This error only occurs when using
14/// convenience routines for building an NFA directly from a pattern string.
15///
16/// Otherwise, errors typically occur when a limit has been breached. For
17/// example, if the total heap usage of the compiled NFA exceeds the limit
18/// set by [`Config::nfa_size_limit`](crate::nfa::thompson::Config), then
19/// building the NFA will fail.
20#[derive(#[automatically_derived]
impl ::core::clone::Clone for BuildError {
#[inline]
fn clone(&self) -> BuildError {
BuildError { kind: ::core::clone::Clone::clone(&self.kind) }
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for BuildError {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f, "BuildError",
"kind", &&self.kind)
}
}Debug)]
21pub struct BuildError {
22 kind: BuildErrorKind,
23}
2425/// The kind of error that occurred during the construction of a thompson NFA.
26#[derive(#[automatically_derived]
impl ::core::clone::Clone for BuildErrorKind {
#[inline]
fn clone(&self) -> BuildErrorKind {
match self {
BuildErrorKind::Syntax(__self_0) =>
BuildErrorKind::Syntax(::core::clone::Clone::clone(__self_0)),
BuildErrorKind::Captures(__self_0) =>
BuildErrorKind::Captures(::core::clone::Clone::clone(__self_0)),
BuildErrorKind::Word(__self_0) =>
BuildErrorKind::Word(::core::clone::Clone::clone(__self_0)),
BuildErrorKind::TooManyPatterns { given: __self_0, limit: __self_1
} =>
BuildErrorKind::TooManyPatterns {
given: ::core::clone::Clone::clone(__self_0),
limit: ::core::clone::Clone::clone(__self_1),
},
BuildErrorKind::TooManyStates { given: __self_0, limit: __self_1 }
=>
BuildErrorKind::TooManyStates {
given: ::core::clone::Clone::clone(__self_0),
limit: ::core::clone::Clone::clone(__self_1),
},
BuildErrorKind::ExceededSizeLimit { limit: __self_0 } =>
BuildErrorKind::ExceededSizeLimit {
limit: ::core::clone::Clone::clone(__self_0),
},
BuildErrorKind::InvalidCaptureIndex { index: __self_0 } =>
BuildErrorKind::InvalidCaptureIndex {
index: ::core::clone::Clone::clone(__self_0),
},
BuildErrorKind::UnsupportedCaptures =>
BuildErrorKind::UnsupportedCaptures,
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for BuildErrorKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
BuildErrorKind::Syntax(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Syntax",
&__self_0),
BuildErrorKind::Captures(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Captures", &__self_0),
BuildErrorKind::Word(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Word",
&__self_0),
BuildErrorKind::TooManyPatterns { given: __self_0, limit: __self_1
} =>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"TooManyPatterns", "given", __self_0, "limit", &__self_1),
BuildErrorKind::TooManyStates { given: __self_0, limit: __self_1 }
=>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"TooManyStates", "given", __self_0, "limit", &__self_1),
BuildErrorKind::ExceededSizeLimit { limit: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"ExceededSizeLimit", "limit", &__self_0),
BuildErrorKind::InvalidCaptureIndex { index: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"InvalidCaptureIndex", "index", &__self_0),
BuildErrorKind::UnsupportedCaptures =>
::core::fmt::Formatter::write_str(f, "UnsupportedCaptures"),
}
}
}Debug)]
27enum BuildErrorKind {
28/// An error that occurred while parsing a regular expression. Note that
29 /// this error may be printed over multiple lines, and is generally
30 /// intended to be end user readable on its own.
31#[cfg(feature = "syntax")]
32Syntax(regex_syntax::Error),
33/// An error that occurs if the capturing groups provided to an NFA builder
34 /// do not satisfy the documented invariants. For example, things like
35 /// too many groups, missing groups, having the first (zeroth) group be
36 /// named or duplicate group names within the same pattern.
37Captures(captures::GroupInfoError),
38/// An error that occurs when an NFA contains a Unicode word boundary, but
39 /// where the crate was compiled without the necessary data for dealing
40 /// with Unicode word boundaries.
41Word(look::UnicodeWordBoundaryError),
42/// An error that occurs if too many patterns were given to the NFA
43 /// compiler.
44TooManyPatterns {
45/// The number of patterns given, which exceeds the limit.
46given: usize,
47/// The limit on the number of patterns.
48limit: usize,
49 },
50/// An error that occurs if too states are produced while building an NFA.
51TooManyStates {
52/// The minimum number of states that are desired, which exceeds the
53 /// limit.
54given: usize,
55/// The limit on the number of states.
56limit: usize,
57 },
58/// An error that occurs when NFA compilation exceeds a configured heap
59 /// limit.
60ExceededSizeLimit {
61/// The configured limit, in bytes.
62limit: usize,
63 },
64/// An error that occurs when an invalid capture group index is added to
65 /// the NFA. An "invalid" index can be one that would otherwise overflow
66 /// a `usize` on the current target.
67InvalidCaptureIndex {
68/// The invalid index that was given.
69index: u32,
70 },
71/// An error that occurs when one tries to build a reverse NFA with
72 /// captures enabled. Currently, this isn't supported, but we probably
73 /// should support it at some point.
74#[cfg(feature = "syntax")]
75UnsupportedCaptures,
76}
7778impl BuildError {
79/// If this error occurred because the NFA exceeded the configured size
80 /// limit before being built, then this returns the configured size limit.
81 ///
82 /// The limit returned is what was configured, and corresponds to the
83 /// maximum amount of heap usage in bytes.
84pub fn size_limit(&self) -> Option<usize> {
85match self.kind {
86 BuildErrorKind::ExceededSizeLimit { limit } => Some(limit),
87_ => None,
88 }
89 }
9091fn kind(&self) -> &BuildErrorKind {
92&self.kind
93 }
9495#[cfg(feature = "syntax")]
96pub(crate) fn syntax(err: regex_syntax::Error) -> BuildError {
97BuildError { kind: BuildErrorKind::Syntax(err) }
98 }
99100pub(crate) fn captures(err: captures::GroupInfoError) -> BuildError {
101BuildError { kind: BuildErrorKind::Captures(err) }
102 }
103104pub(crate) fn word(err: look::UnicodeWordBoundaryError) -> BuildError {
105BuildError { kind: BuildErrorKind::Word(err) }
106 }
107108pub(crate) fn too_many_patterns(given: usize) -> BuildError {
109let limit = PatternID::LIMIT;
110BuildError { kind: BuildErrorKind::TooManyPatterns { given, limit } }
111 }
112113pub(crate) fn too_many_states(given: usize) -> BuildError {
114let limit = StateID::LIMIT;
115BuildError { kind: BuildErrorKind::TooManyStates { given, limit } }
116 }
117118pub(crate) fn exceeded_size_limit(limit: usize) -> BuildError {
119BuildError { kind: BuildErrorKind::ExceededSizeLimit { limit } }
120 }
121122pub(crate) fn invalid_capture_index(index: u32) -> BuildError {
123BuildError { kind: BuildErrorKind::InvalidCaptureIndex { index } }
124 }
125126#[cfg(feature = "syntax")]
127pub(crate) fn unsupported_captures() -> BuildError {
128BuildError { kind: BuildErrorKind::UnsupportedCaptures }
129 }
130}
131132#[cfg(feature = "std")]
133impl std::error::Errorfor BuildError {
134fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
135match self.kind() {
136#[cfg(feature = "syntax")]
137BuildErrorKind::Syntax(ref err) => Some(err),
138 BuildErrorKind::Captures(ref err) => Some(err),
139_ => None,
140 }
141 }
142}
143144impl core::fmt::Displayfor BuildError {
145fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
146match self.kind() {
147#[cfg(feature = "syntax")]
148 BuildErrorKind::Syntax(_) => f.write_fmt(format_args!("error parsing regex"))write!(f, "error parsing regex"),
149 BuildErrorKind::Captures(_) => {
150f.write_fmt(format_args!("error with capture groups"))write!(f, "error with capture groups")151 }
152 BuildErrorKind::Word(_) => {
153f.write_fmt(format_args!("NFA contains Unicode word boundary"))write!(f, "NFA contains Unicode word boundary")154 }
155 BuildErrorKind::TooManyPatterns { given, limit } => f.write_fmt(format_args!("attempted to compile {0} patterns, which exceeds the limit of {1}",
given, limit))write!(
156f,
157"attempted to compile {given} patterns, \
158 which exceeds the limit of {limit}",
159 ),
160 BuildErrorKind::TooManyStates { given, limit } => f.write_fmt(format_args!("attempted to compile {0} NFA states, which exceeds the limit of {1}",
given, limit))write!(
161f,
162"attempted to compile {given} NFA states, \
163 which exceeds the limit of {limit}",
164 ),
165 BuildErrorKind::ExceededSizeLimit { limit } => f.write_fmt(format_args!("heap usage during NFA compilation exceeded limit of {0}",
limit))write!(
166f,
167"heap usage during NFA compilation exceeded limit of {limit}",
168 ),
169 BuildErrorKind::InvalidCaptureIndex { index } => f.write_fmt(format_args!("capture group index {0} is invalid (too big or discontinuous)",
index))write!(
170f,
171"capture group index {index} is invalid \
172 (too big or discontinuous)",
173 ),
174#[cfg(feature = "syntax")]
175 BuildErrorKind::UnsupportedCaptures => f.write_fmt(format_args!("currently captures must be disabled when compiling a reverse NFA"))write!(
176f,
177"currently captures must be disabled when compiling \
178 a reverse NFA",
179 ),
180 }
181 }
182}