Skip to main content

fancy_regex/
error.rs

1use std::fmt;
2
3/// Result type for this crate with specific error enum.
4pub type Result<T> = ::std::result::Result<T, Error>;
5
6pub type ParseErrorPosition = usize;
7
8/// An error as the result of parsing, compiling or running a regex.
9#[derive(Debug)]
10pub enum Error {
11    /// An error as a result of parsing a regex pattern, with the position where the error occurred
12    ParseError(ParseErrorPosition, ParseError),
13    /// An error as a result of compiling a regex
14    CompileError(CompileError),
15    /// An error as a result of running a regex
16    RuntimeError(RuntimeError),
17
18    /// This enum may grow additional variants, so this makes sure clients don't count on exhaustive
19    /// matching. Otherwise, adding a new variant could break existing code.
20    #[doc(hidden)]
21    __Nonexhaustive,
22}
23
24/// An error for the result of parsing a regex pattern.
25#[derive(Debug)]
26pub enum ParseError {
27    /// General parsing error
28    GeneralParseError(String),
29    /// Opening parenthesis without closing parenthesis, e.g. `(a|b`
30    UnclosedOpenParen,
31    /// Invalid repeat syntax
32    InvalidRepeat,
33    /// Pattern too deeply nested
34    RecursionExceeded,
35    /// Backslash without following character
36    TrailingBackslash,
37    /// Invalid escape
38    InvalidEscape(String),
39    /// Unicode escape not closed
40    UnclosedUnicodeName,
41    /// Invalid hex escape
42    InvalidHex,
43    /// Invalid codepoint for hex or unicode escape
44    InvalidCodepointValue,
45    /// Invalid character class
46    InvalidClass,
47    /// Unknown group flag
48    UnknownFlag(String),
49    /// Disabling Unicode not supported
50    NonUnicodeUnsupported,
51    /// Invalid back reference
52    InvalidBackref,
53    /// Quantifier on lookaround or other zero-width assertion
54    TargetNotRepeatable,
55    /// Couldn't parse group name
56    InvalidGroupName,
57    /// Invalid group id in escape sequence
58    InvalidGroupNameBackref(String),
59
60    /// This enum may grow additional variants, so this makes sure clients don't count on exhaustive
61    /// matching. Otherwise, adding a new variant could break existing code.
62    #[doc(hidden)]
63    __Nonexhaustive,
64}
65
66/// An error as the result of compiling a regex.
67#[derive(Debug)]
68pub enum CompileError {
69    /// Regex crate error
70    InnerError(regex::Error),
71    /// Look-behind assertion without constant size
72    LookBehindNotConst,
73    /// Couldn't parse group name
74    InvalidGroupName,
75    /// Invalid group id in escape sequence
76    InvalidGroupNameBackref(String),
77    /// Invalid back reference
78    InvalidBackref,
79    /// Once named groups are used you cannot refer to groups by number
80    NamedBackrefOnly,
81
82    /// This enum may grow additional variants, so this makes sure clients don't count on exhaustive
83    /// matching. Otherwise, adding a new variant could break existing code.
84    #[doc(hidden)]
85    __Nonexhaustive,
86}
87
88/// An error as the result of executing a regex.
89#[derive(Debug)]
90pub enum RuntimeError {
91    /// Max stack size exceeded for backtracking while executing regex.
92    StackOverflow,
93    /// Max limit for backtracking count exceeded while executing the regex.
94    /// Configure using
95    /// [`RegexBuilder::backtrack_limit`](struct.RegexBuilder.html#method.backtrack_limit).
96    BacktrackLimitExceeded,
97
98    /// This enum may grow additional variants, so this makes sure clients don't count on exhaustive
99    /// matching. Otherwise, adding a new variant could break existing code.
100    #[doc(hidden)]
101    __Nonexhaustive,
102}
103
104impl ::std::error::Error for Error {}
105
106impl fmt::Display for ParseError {
107    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
108        match self {
109            ParseError::GeneralParseError(s) => write!(f, "General parsing error: {}", s),
110            ParseError::UnclosedOpenParen => {
111                write!(f, "Opening parenthesis without closing parenthesis")
112            }
113            ParseError::InvalidRepeat => write!(f, "Invalid repeat syntax"),
114            ParseError::RecursionExceeded => write!(f, "Pattern too deeply nested"),
115            ParseError::TrailingBackslash => write!(f, "Backslash without following character"),
116            ParseError::InvalidEscape(s) => write!(f, "Invalid escape: {}", s),
117            ParseError::UnclosedUnicodeName => write!(f, "Unicode escape not closed"),
118            ParseError::InvalidHex => write!(f, "Invalid hex escape"),
119            ParseError::InvalidCodepointValue => {
120                write!(f, "Invalid codepoint for hex or unicode escape")
121            }
122            ParseError::InvalidClass => write!(f, "Invalid character class"),
123            ParseError::UnknownFlag(s) => write!(f, "Unknown group flag: {}", s),
124            ParseError::NonUnicodeUnsupported => write!(f, "Disabling Unicode not supported"),
125            ParseError::InvalidBackref => write!(f, "Invalid back reference"),
126            ParseError::InvalidGroupName => write!(f, "Could not parse group name"),
127            ParseError::InvalidGroupNameBackref(s) => {
128                write!(f, "Invalid group name in back reference: {}", s)
129            }
130            ParseError::TargetNotRepeatable => write!(f, "Target of repeat operator is invalid"),
131
132            ParseError::__Nonexhaustive => unreachable!(),
133        }
134    }
135}
136
137impl fmt::Display for CompileError {
138    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
139        match self {
140            CompileError::InnerError(e) => write!(f, "Regex error: {}", e),
141            CompileError::LookBehindNotConst => {
142                write!(f, "Look-behind assertion without constant size")
143            },
144            CompileError::InvalidGroupName => write!(f, "Could not parse group name"),
145            CompileError::InvalidGroupNameBackref(s) => write!(f, "Invalid group name in back reference: {}", s),
146            CompileError::InvalidBackref => write!(f, "Invalid back reference"),
147            CompileError::NamedBackrefOnly => write!(f, "Numbered backref/call not allowed because named group was used, use a named backref instead"),
148
149            CompileError::__Nonexhaustive => unreachable!(),
150        }
151    }
152}
153
154impl fmt::Display for RuntimeError {
155    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
156        match self {
157            RuntimeError::StackOverflow => write!(f, "Max stack size exceeded for backtracking"),
158            RuntimeError::BacktrackLimitExceeded => {
159                write!(f, "Max limit for backtracking count exceeded")
160            }
161
162            RuntimeError::__Nonexhaustive => unreachable!(),
163        }
164    }
165}
166
167impl fmt::Display for Error {
168    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
169        match self {
170            Error::ParseError(position, parse_error) => {
171                write!(f, "Parsing error at position {}: {}", position, parse_error)
172            }
173            Error::CompileError(compile_error) => {
174                write!(f, "Error compiling regex: {}", compile_error)
175            }
176            Error::RuntimeError(runtime_error) => {
177                write!(f, "Error executing regex: {}", runtime_error)
178            }
179
180            Error::__Nonexhaustive => unreachable!(),
181        }
182    }
183}
184
185impl From<CompileError> for Error {
186    fn from(compile_error: CompileError) -> Self {
187        Error::CompileError(compile_error)
188    }
189}