blob: 52f02e888f37c90bc2417636e732f90904108b4e [file] [log] [blame]
use crate::util::id::{PatternID, StateID};
/// An error that can occured during the construction of a thompson NFA.
///
/// This error does not provide many introspection capabilities. There are
/// generally only two things you can do with it:
///
/// * Obtain a human readable message via its `std::fmt::Display` impl.
/// * Access an underlying [`regex_syntax::Error`] type from its `source`
/// method via the `std::error::Error` trait. This error only occurs when using
/// convenience routines for building an NFA directly from a pattern string.
///
/// Otherwise, errors typically occur when a limit has been breeched. For
/// example, if the total heap usage of the compiled NFA exceeds the limit
/// set by [`Config::nfa_size_limit`](crate::nfa::thompson::Config), then
/// building the NFA will fail.
#[derive(Clone, Debug)]
pub struct Error {
kind: ErrorKind,
}
/// The kind of error that occurred during the construction of a thompson NFA.
#[derive(Clone, Debug)]
enum ErrorKind {
/// An error that occurred while parsing a regular expression. Note that
/// this error may be printed over multiple lines, and is generally
/// intended to be end user readable on its own.
Syntax(regex_syntax::Error),
/// An error that occurs if too many patterns were given to the NFA
/// compiler.
TooManyPatterns {
/// The number of patterns given, which exceeds the limit.
given: usize,
/// The limit on the number of patterns.
limit: usize,
},
/// An error that occurs if too states are produced while building an NFA.
TooManyStates {
/// The minimum number of states that are desired, which exceeds the
/// limit.
given: usize,
/// The limit on the number of states.
limit: usize,
},
/// An error that occurs when NFA compilation exceeds a configured heap
/// limit.
ExceededSizeLimit {
/// The configured limit, in bytes.
limit: usize,
},
/// An error that occurs when an invalid capture group index is added to
/// the NFA. An "invalid" index can be one that is too big (e.g., results
/// in an integer overflow) or one that is discontinuous from previous
/// capture group indices added.
InvalidCaptureIndex {
/// The invalid index that was given.
index: usize,
},
/// An error that occurs when an NFA contains a Unicode word boundary, but
/// where the crate was compiled without the necessary data for dealing
/// with Unicode word boundaries.
UnicodeWordUnavailable,
}
impl Error {
fn kind(&self) -> &ErrorKind {
&self.kind
}
pub(crate) fn syntax(err: regex_syntax::Error) -> Error {
Error { kind: ErrorKind::Syntax(err) }
}
pub(crate) fn too_many_patterns(given: usize) -> Error {
let limit = PatternID::LIMIT;
Error { kind: ErrorKind::TooManyPatterns { given, limit } }
}
pub(crate) fn too_many_states(given: usize) -> Error {
let limit = StateID::LIMIT;
Error { kind: ErrorKind::TooManyStates { given, limit } }
}
pub(crate) fn exceeded_size_limit(limit: usize) -> Error {
Error { kind: ErrorKind::ExceededSizeLimit { limit } }
}
pub(crate) fn invalid_capture_index(index: usize) -> Error {
Error { kind: ErrorKind::InvalidCaptureIndex { index } }
}
pub(crate) fn unicode_word_unavailable() -> Error {
Error { kind: ErrorKind::UnicodeWordUnavailable }
}
}
#[cfg(feature = "std")]
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self.kind() {
ErrorKind::Syntax(ref err) => Some(err),
ErrorKind::TooManyPatterns { .. } => None,
ErrorKind::TooManyStates { .. } => None,
ErrorKind::ExceededSizeLimit { .. } => None,
ErrorKind::InvalidCaptureIndex { .. } => None,
ErrorKind::UnicodeWordUnavailable => None,
}
}
}
impl core::fmt::Display for Error {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self.kind() {
ErrorKind::Syntax(_) => write!(f, "error parsing regex"),
ErrorKind::TooManyPatterns { given, limit } => write!(
f,
"attemped to compile {} patterns, \
which exceeds the limit of {}",
given, limit,
),
ErrorKind::TooManyStates { given, limit } => write!(
f,
"attemped to compile {} NFA states, \
which exceeds the limit of {}",
given, limit,
),
ErrorKind::ExceededSizeLimit { limit } => write!(
f,
"heap usage during NFA compilation exceeded limit of {}",
limit,
),
ErrorKind::InvalidCaptureIndex { index } => write!(
f,
"capture group index {} is invalid (too big or discontinuous)",
index,
),
ErrorKind::UnicodeWordUnavailable => write!(
f,
"crate has been compiled without Unicode word boundary \
support, but the NFA contains Unicode word boundary \
assertions",
),
}
}
}