1 use std::error;
2 use std::fmt;
3 use std::result;
4 
5 use regex_syntax;
6 
7 pub type Result<T> = result::Result<T, Error>;
8 
9 /// An error that occurred during the construction of a DFA.
10 #[derive(Clone, Debug)]
11 pub struct Error {
12     kind: ErrorKind,
13 }
14 
15 /// The kind of error that occurred.
16 #[derive(Clone, Debug)]
17 pub enum ErrorKind {
18     /// An error that occurred while parsing a regular expression. Note that
19     /// this error may be printed over multiple lines, and is generally
20     /// intended to be end user readable on its own.
21     Syntax(String),
22     /// An error that occurred because an unsupported regex feature was used.
23     /// The message string describes which unsupported feature was used.
24     ///
25     /// The primary regex features that are unsupported are those that require
26     /// look-around, such as the `^` and `$` anchors and the word boundary
27     /// assertion `\b`. These may be supported in the future.
28     Unsupported(String),
29     /// An error that occurred when attempting to serialize a DFA to bytes.
30     Serialize(String),
31     /// An error that occurs when constructing a DFA would require the use of
32     /// a state ID that overflows the chosen state ID representation. For
33     /// example, if one is using `u8` for state IDs and builds a DFA with
34     /// 257 states, then the last state's ID will be `256` which cannot be
35     /// represented with `u8`.
36     ///
37     /// Typically, this error occurs in the determinization process of building
38     /// a DFA (the conversion step from NFA to DFA). It can also occur when
39     /// trying to build a smaller DFA from an existing one.
40     StateIDOverflow {
41         /// The maximum possible state ID.
42         max: usize,
43     },
44     /// An error that occurs when premultiplication of state IDs is requested,
45     /// but doing so would overflow the chosen state ID representation.
46     ///
47     /// When `max == requested_max`, then the state ID would overflow `usize`.
48     PremultiplyOverflow {
49         /// The maximum possible state id.
50         max: usize,
51         /// The maximum ID required by premultiplication.
52         requested_max: usize,
53     },
54 }
55 
56 impl Error {
57     /// Return the kind of this error.
kind(&self) -> &ErrorKind58     pub fn kind(&self) -> &ErrorKind {
59         &self.kind
60     }
61 
syntax(err: regex_syntax::Error) -> Error62     pub(crate) fn syntax(err: regex_syntax::Error) -> Error {
63         Error { kind: ErrorKind::Syntax(err.to_string()) }
64     }
65 
unsupported_anchor() -> Error66     pub(crate) fn unsupported_anchor() -> Error {
67         let msg = r"anchors such as ^, $, \A and \z are not supported";
68         Error { kind: ErrorKind::Unsupported(msg.to_string()) }
69     }
70 
unsupported_word() -> Error71     pub(crate) fn unsupported_word() -> Error {
72         let msg = r"word boundary assertions (\b and \B) are not supported";
73         Error { kind: ErrorKind::Unsupported(msg.to_string()) }
74     }
75 
unsupported_longest_match() -> Error76     pub(crate) fn unsupported_longest_match() -> Error {
77         let msg = "unachored searches with longest match \
78                    semantics are not supported";
79         Error { kind: ErrorKind::Unsupported(msg.to_string()) }
80     }
81 
serialize(message: &str) -> Error82     pub(crate) fn serialize(message: &str) -> Error {
83         Error { kind: ErrorKind::Serialize(message.to_string()) }
84     }
85 
state_id_overflow(max: usize) -> Error86     pub(crate) fn state_id_overflow(max: usize) -> Error {
87         Error { kind: ErrorKind::StateIDOverflow { max } }
88     }
89 
premultiply_overflow( max: usize, requested_max: usize, ) -> Error90     pub(crate) fn premultiply_overflow(
91         max: usize,
92         requested_max: usize,
93     ) -> Error {
94         Error { kind: ErrorKind::PremultiplyOverflow { max, requested_max } }
95     }
96 }
97 
98 impl error::Error for Error {
description(&self) -> &str99     fn description(&self) -> &str {
100         match self.kind {
101             ErrorKind::Syntax(_) => "syntax error",
102             ErrorKind::Unsupported(_) => "unsupported syntax",
103             ErrorKind::Serialize(_) => "serialization error",
104             ErrorKind::StateIDOverflow { .. } => {
105                 "state id representation too small"
106             }
107             ErrorKind::PremultiplyOverflow { .. } => {
108                 "state id representation too small for premultiplication"
109             }
110         }
111     }
112 }
113 
114 impl fmt::Display for Error {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result115     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
116         match self.kind {
117             ErrorKind::Syntax(ref msg) => write!(f, "{}", msg),
118             ErrorKind::Unsupported(ref msg) => write!(f, "{}", msg),
119             ErrorKind::Serialize(ref msg) => {
120                 write!(f, "DFA serialization error: {}", msg)
121             }
122             ErrorKind::StateIDOverflow { max } => write!(
123                 f,
124                 "building the DFA failed because it required building \
125                  more states that can be identified, where the maximum \
126                  ID for the chosen representation is {}",
127                 max,
128             ),
129             ErrorKind::PremultiplyOverflow { max, requested_max } => {
130                 if max == requested_max {
131                     write!(
132                         f,
133                         "premultiplication of states requires the ability to \
134                          represent a state ID greater than what can fit on \
135                          this platform's usize, which is {}",
136                         ::std::usize::MAX,
137                     )
138                 } else {
139                     write!(
140                         f,
141                         "premultiplication of states requires the ability to \
142                          represent at least a state ID of {}, but the chosen \
143                          representation only permits a maximum state ID of {}",
144                         requested_max, max,
145                     )
146                 }
147             }
148         }
149     }
150 }
151