1use std::fmt;
2use std::iter::repeat;
3
4/// An error that occurred during parsing or compiling a regular expression.
5#[derive(Clone, PartialEq)]
6pub enum Error {
7 /// A syntax error.
8 Syntax(String),
9 /// The compiled program exceeded the set size
10 /// limit. The argument is the size limit imposed by
11 /// [`RegexBuilder::size_limit`](crate::RegexBuilder::size_limit). Even
12 /// when not configured explicitly, it defaults to a reasonable limit.
13 ///
14 /// If you're getting this error, it occurred because your regex has been
15 /// compiled to an intermediate state that is too big. It is important to
16 /// note that exceeding this limit does _not_ mean the regex is too big to
17 /// _work_, but rather, the regex is big enough that it may wind up being
18 /// surprisingly slow when used in a search. In other words, this error is
19 /// meant to be a practical heuristic for avoiding a performance footgun,
20 /// and especially so for the case where the regex pattern is coming from
21 /// an untrusted source.
22 ///
23 /// There are generally two ways to move forward if you hit this error.
24 /// The first is to find some way to use a smaller regex. The second is to
25 /// increase the size limit via `RegexBuilder::size_limit`. However, if
26 /// your regex pattern is not from a trusted source, then neither of these
27 /// approaches may be appropriate. Instead, you'll have to determine just
28 /// how big of a regex you want to allow.
29 CompiledTooBig(usize),
30 /// Hints that destructuring should not be exhaustive.
31 ///
32 /// This enum may grow additional variants, so this makes sure clients
33 /// don't count on exhaustive matching. (Otherwise, adding a new variant
34 /// could break existing code.)
35 #[doc(hidden)]
36 __Nonexhaustive,
37}
38
39impl ::std::error::Error for Error {
40 // TODO: Remove this method entirely on the next breaking semver release.
41 #[allow(deprecated)]
42 fn description(&self) -> &str {
43 match *self {
44 Error::Syntax(ref err: &String) => err,
45 Error::CompiledTooBig(_) => "compiled program too big",
46 Error::__Nonexhaustive => unreachable!(),
47 }
48 }
49}
50
51impl fmt::Display for Error {
52 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53 match *self {
54 Error::Syntax(ref err: &String) => err.fmt(f),
55 Error::CompiledTooBig(limit: usize) => write!(
56 f,
57 "Compiled regex exceeds size limit of {} bytes.",
58 limit
59 ),
60 Error::__Nonexhaustive => unreachable!(),
61 }
62 }
63}
64
65// We implement our own Debug implementation so that we show nicer syntax
66// errors when people use `Regex::new(...).unwrap()`. It's a little weird,
67// but the `Syntax` variant is already storing a `String` anyway, so we might
68// as well format it nicely.
69impl fmt::Debug for Error {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 match *self {
72 Error::Syntax(ref err: &String) => {
73 let hr: String = repeat(elt:'~').take(79).collect();
74 writeln!(f, "Syntax(")?;
75 writeln!(f, "{}", hr)?;
76 writeln!(f, "{}", err)?;
77 writeln!(f, "{}", hr)?;
78 write!(f, ")")?;
79 Ok(())
80 }
81 Error::CompiledTooBig(limit: usize) => {
82 f.debug_tuple(name:"CompiledTooBig").field(&limit).finish()
83 }
84 Error::__Nonexhaustive => {
85 f.debug_tuple(name:"__Nonexhaustive").finish()
86 }
87 }
88 }
89}
90