1/*!
2Defines an abstract syntax for regular expressions.
3*/
45use core::cmp::Ordering;
67use alloc::{boxed::Box, string::String, vec, vec::Vec};
89pub use crate::ast::visitor::{visit, Visitor};
1011pub mod parse;
12pub mod print;
13mod visitor;
1415/// An error that occurred while parsing a regular expression into an abstract
16/// syntax tree.
17///
18/// Note that not all ASTs represents a valid regular expression. For example,
19/// an AST is constructed without error for `\p{Quux}`, but `Quux` is not a
20/// valid Unicode property name. That particular error is reported when
21/// translating an AST to the high-level intermediate representation (`HIR`).
22#[derive(#[automatically_derived]impl ::core::clone::Clone for Error {
#[inline]
fn clone(&self) -> Self {
Error {
kind: ::core::clone::Clone::clone(&self.kind),
pattern: ::core::clone::Clone::clone(&self.pattern),
span: ::core::clone::Clone::clone(&self.span),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for Error {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f,
"Error kind pattern span", &self.kind, &self.pattern, &&self.span)
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for Error {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<ErrorKind>;
let _: ::core::cmp::AssertParamIsEq<String>;
let _: ::core::cmp::AssertParamIsEq<Span>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for Error { }
#[automatically_derived]impl ::core::cmp::PartialEq for Error {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.kind == other.kind && self.pattern == other.pattern &&
self.span == other.span
}
}PartialEq)]
23#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
24pub struct Error {
25/// The kind of error.
26kind: ErrorKind,
27/// The original pattern that the parser generated the error from. Every
28 /// span in an error is a valid range into this string.
29pattern: String,
30/// The span of this error.
31span: Span,
32}
3334impl Error {
35/// Return the type of this error.
36pub fn kind(&self) -> &ErrorKind {
37&self.kind
38 }
3940/// The original pattern string in which this error occurred.
41 ///
42 /// Every span reported by this error is reported in terms of this string.
43pub fn pattern(&self) -> &str {
44&self.pattern
45 }
4647/// Return the span at which this error occurred.
48pub fn span(&self) -> &Span {
49&self.span
50 }
5152/// Return an auxiliary span. This span exists only for some errors that
53 /// benefit from being able to point to two locations in the original
54 /// regular expression. For example, "duplicate" errors will have the
55 /// main error position set to the duplicate occurrence while its
56 /// auxiliary span will be set to the initial occurrence.
57pub fn auxiliary_span(&self) -> Option<&Span> {
58use self::ErrorKind::*;
59match self.kind {
60FlagDuplicate { ref original } => Some(original),
61FlagRepeatedNegation { ref original, .. } => Some(original),
62GroupNameDuplicate { ref original, .. } => Some(original),
63_ => None,
64 }
65 }
66}
6768/// The type of an error that occurred while building an AST.
69///
70/// This error type is marked as `non_exhaustive`. This means that adding a
71/// new variant is not considered a breaking change.
72#[non_exhaustive]
73#[derive(#[automatically_derived]impl ::core::clone::Clone for ErrorKind {
#[inline]
fn clone(&self) -> Self {
match self {
Self::CaptureLimitExceeded => ErrorKind::CaptureLimitExceeded,
Self::ClassEscapeInvalid => ErrorKind::ClassEscapeInvalid,
Self::ClassRangeInvalid => ErrorKind::ClassRangeInvalid,
Self::ClassRangeLiteral => ErrorKind::ClassRangeLiteral,
Self::ClassUnclosed => ErrorKind::ClassUnclosed,
Self::DecimalEmpty => ErrorKind::DecimalEmpty,
Self::DecimalInvalid => ErrorKind::DecimalInvalid,
Self::EscapeHexEmpty => ErrorKind::EscapeHexEmpty,
Self::EscapeHexInvalid => ErrorKind::EscapeHexInvalid,
Self::EscapeHexInvalidDigit => ErrorKind::EscapeHexInvalidDigit,
Self::EscapeUnexpectedEof => ErrorKind::EscapeUnexpectedEof,
Self::EscapeUnrecognized => ErrorKind::EscapeUnrecognized,
Self::FlagDanglingNegation => ErrorKind::FlagDanglingNegation,
Self::FlagDuplicate { original: __self_0 } =>
ErrorKind::FlagDuplicate {
original: ::core::clone::Clone::clone(__self_0),
},
Self::FlagRepeatedNegation { original: __self_0 } =>
ErrorKind::FlagRepeatedNegation {
original: ::core::clone::Clone::clone(__self_0),
},
Self::FlagUnexpectedEof => ErrorKind::FlagUnexpectedEof,
Self::FlagUnrecognized => ErrorKind::FlagUnrecognized,
Self::GroupNameDuplicate { original: __self_0 } =>
ErrorKind::GroupNameDuplicate {
original: ::core::clone::Clone::clone(__self_0),
},
Self::GroupNameEmpty => ErrorKind::GroupNameEmpty,
Self::GroupNameInvalid => ErrorKind::GroupNameInvalid,
Self::GroupNameUnexpectedEof => ErrorKind::GroupNameUnexpectedEof,
Self::GroupUnclosed => ErrorKind::GroupUnclosed,
Self::GroupUnopened => ErrorKind::GroupUnopened,
Self::NestLimitExceeded(__self_0) =>
ErrorKind::NestLimitExceeded(::core::clone::Clone::clone(__self_0)),
Self::RepetitionCountInvalid => ErrorKind::RepetitionCountInvalid,
Self::RepetitionCountDecimalEmpty =>
ErrorKind::RepetitionCountDecimalEmpty,
Self::RepetitionCountUnclosed =>
ErrorKind::RepetitionCountUnclosed,
Self::RepetitionMissing => ErrorKind::RepetitionMissing,
Self::SpecialWordBoundaryUnclosed =>
ErrorKind::SpecialWordBoundaryUnclosed,
Self::SpecialWordBoundaryUnrecognized =>
ErrorKind::SpecialWordBoundaryUnrecognized,
Self::SpecialWordOrRepetitionUnexpectedEof =>
ErrorKind::SpecialWordOrRepetitionUnexpectedEof,
Self::UnicodeClassInvalid => ErrorKind::UnicodeClassInvalid,
Self::UnsupportedBackreference =>
ErrorKind::UnsupportedBackreference,
Self::UnsupportedLookAround => ErrorKind::UnsupportedLookAround,
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for ErrorKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Self::CaptureLimitExceeded =>
::core::fmt::Formatter::write_str(f, "CaptureLimitExceeded"),
Self::ClassEscapeInvalid =>
::core::fmt::Formatter::write_str(f, "ClassEscapeInvalid"),
Self::ClassRangeInvalid =>
::core::fmt::Formatter::write_str(f, "ClassRangeInvalid"),
Self::ClassRangeLiteral =>
::core::fmt::Formatter::write_str(f, "ClassRangeLiteral"),
Self::ClassUnclosed =>
::core::fmt::Formatter::write_str(f, "ClassUnclosed"),
Self::DecimalEmpty =>
::core::fmt::Formatter::write_str(f, "DecimalEmpty"),
Self::DecimalInvalid =>
::core::fmt::Formatter::write_str(f, "DecimalInvalid"),
Self::EscapeHexEmpty =>
::core::fmt::Formatter::write_str(f, "EscapeHexEmpty"),
Self::EscapeHexInvalid =>
::core::fmt::Formatter::write_str(f, "EscapeHexInvalid"),
Self::EscapeHexInvalidDigit =>
::core::fmt::Formatter::write_str(f, "EscapeHexInvalidDigit"),
Self::EscapeUnexpectedEof =>
::core::fmt::Formatter::write_str(f, "EscapeUnexpectedEof"),
Self::EscapeUnrecognized =>
::core::fmt::Formatter::write_str(f, "EscapeUnrecognized"),
Self::FlagDanglingNegation =>
::core::fmt::Formatter::write_str(f, "FlagDanglingNegation"),
Self::FlagDuplicate { original: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"FlagDuplicate original", &__self_0),
Self::FlagRepeatedNegation { original: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"FlagRepeatedNegation original", &__self_0),
Self::FlagUnexpectedEof =>
::core::fmt::Formatter::write_str(f, "FlagUnexpectedEof"),
Self::FlagUnrecognized =>
::core::fmt::Formatter::write_str(f, "FlagUnrecognized"),
Self::GroupNameDuplicate { original: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"GroupNameDuplicate original", &__self_0),
Self::GroupNameEmpty =>
::core::fmt::Formatter::write_str(f, "GroupNameEmpty"),
Self::GroupNameInvalid =>
::core::fmt::Formatter::write_str(f, "GroupNameInvalid"),
Self::GroupNameUnexpectedEof =>
::core::fmt::Formatter::write_str(f,
"GroupNameUnexpectedEof"),
Self::GroupUnclosed =>
::core::fmt::Formatter::write_str(f, "GroupUnclosed"),
Self::GroupUnopened =>
::core::fmt::Formatter::write_str(f, "GroupUnopened"),
Self::NestLimitExceeded(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"NestLimitExceeded", &__self_0),
Self::RepetitionCountInvalid =>
::core::fmt::Formatter::write_str(f,
"RepetitionCountInvalid"),
Self::RepetitionCountDecimalEmpty =>
::core::fmt::Formatter::write_str(f,
"RepetitionCountDecimalEmpty"),
Self::RepetitionCountUnclosed =>
::core::fmt::Formatter::write_str(f,
"RepetitionCountUnclosed"),
Self::RepetitionMissing =>
::core::fmt::Formatter::write_str(f, "RepetitionMissing"),
Self::SpecialWordBoundaryUnclosed =>
::core::fmt::Formatter::write_str(f,
"SpecialWordBoundaryUnclosed"),
Self::SpecialWordBoundaryUnrecognized =>
::core::fmt::Formatter::write_str(f,
"SpecialWordBoundaryUnrecognized"),
Self::SpecialWordOrRepetitionUnexpectedEof =>
::core::fmt::Formatter::write_str(f,
"SpecialWordOrRepetitionUnexpectedEof"),
Self::UnicodeClassInvalid =>
::core::fmt::Formatter::write_str(f, "UnicodeClassInvalid"),
Self::UnsupportedBackreference =>
::core::fmt::Formatter::write_str(f,
"UnsupportedBackreference"),
Self::UnsupportedLookAround =>
::core::fmt::Formatter::write_str(f, "UnsupportedLookAround"),
}
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for ErrorKind {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Span>;
let _: ::core::cmp::AssertParamIsEq<u32>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for ErrorKind
{
}
#[automatically_derived]impl ::core::cmp::PartialEq for ErrorKind {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other) &&
match (self, other) {
(Self::FlagDuplicate { original: __self_0 },
Self::FlagDuplicate { original: __arg1_0 }) =>
__self_0 == __arg1_0,
(Self::FlagRepeatedNegation { original: __self_0 },
Self::FlagRepeatedNegation { original: __arg1_0 }) =>
__self_0 == __arg1_0,
(Self::GroupNameDuplicate { original: __self_0 },
Self::GroupNameDuplicate { original: __arg1_0 }) =>
__self_0 == __arg1_0,
(Self::NestLimitExceeded(__self_0),
Self::NestLimitExceeded(__arg1_0)) => __self_0 == __arg1_0,
_ => true,
}
}
}PartialEq)]
74#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
75pub enum ErrorKind {
76/// The capturing group limit was exceeded.
77 ///
78 /// Note that this represents a limit on the total number of capturing
79 /// groups in a regex and not necessarily the number of nested capturing
80 /// groups. That is, the nest limit can be low and it is still possible for
81 /// this error to occur.
82CaptureLimitExceeded,
83/// An invalid escape sequence was found in a character class set.
84ClassEscapeInvalid,
85/// An invalid character class range was found. An invalid range is any
86 /// range where the start is greater than the end.
87ClassRangeInvalid,
88/// An invalid range boundary was found in a character class. Range
89 /// boundaries must be a single literal codepoint, but this error indicates
90 /// that something else was found, such as a nested class.
91ClassRangeLiteral,
92/// An opening `[` was found with no corresponding closing `]`.
93ClassUnclosed,
94/// Note that this error variant is no longer used. Namely, a decimal
95 /// number can only appear as a repetition quantifier. When the number
96 /// in a repetition quantifier is empty, then it gets its own specialized
97 /// error, `RepetitionCountDecimalEmpty`.
98DecimalEmpty,
99/// An invalid decimal number was given where one was expected.
100DecimalInvalid,
101/// A bracketed hex literal was empty.
102EscapeHexEmpty,
103/// A bracketed hex literal did not correspond to a Unicode scalar value.
104EscapeHexInvalid,
105/// An invalid hexadecimal digit was found.
106EscapeHexInvalidDigit,
107/// EOF was found before an escape sequence was completed.
108EscapeUnexpectedEof,
109/// An unrecognized escape sequence.
110EscapeUnrecognized,
111/// A dangling negation was used when setting flags, e.g., `i-`.
112FlagDanglingNegation,
113/// A flag was used twice, e.g., `i-i`.
114FlagDuplicate {
115/// The position of the original flag. The error position
116 /// points to the duplicate flag.
117original: Span,
118 },
119/// The negation operator was used twice, e.g., `-i-s`.
120FlagRepeatedNegation {
121/// The position of the original negation operator. The error position
122 /// points to the duplicate negation operator.
123original: Span,
124 },
125/// Expected a flag but got EOF, e.g., `(?`.
126FlagUnexpectedEof,
127/// Unrecognized flag, e.g., `a`.
128FlagUnrecognized,
129/// A duplicate capture name was found.
130GroupNameDuplicate {
131/// The position of the initial occurrence of the capture name. The
132 /// error position itself points to the duplicate occurrence.
133original: Span,
134 },
135/// A capture group name is empty, e.g., `(?P<>abc)`.
136GroupNameEmpty,
137/// An invalid character was seen for a capture group name. This includes
138 /// errors where the first character is a digit (even though subsequent
139 /// characters are allowed to be digits).
140GroupNameInvalid,
141/// A closing `>` could not be found for a capture group name.
142GroupNameUnexpectedEof,
143/// An unclosed group, e.g., `(ab`.
144 ///
145 /// The span of this error corresponds to the unclosed parenthesis.
146GroupUnclosed,
147/// An unopened group, e.g., `ab)`.
148GroupUnopened,
149/// The nest limit was exceeded. The limit stored here is the limit
150 /// configured in the parser.
151NestLimitExceeded(u32),
152/// The range provided in a counted repetition operator is invalid. The
153 /// range is invalid if the start is greater than the end.
154RepetitionCountInvalid,
155/// An opening `{` was not followed by a valid decimal value.
156 /// For example, `x{}` or `x{]}` would fail.
157RepetitionCountDecimalEmpty,
158/// An opening `{` was found with no corresponding closing `}`.
159RepetitionCountUnclosed,
160/// A repetition operator was applied to a missing sub-expression. This
161 /// occurs, for example, in the regex consisting of just a `*` or even
162 /// `(?i)*`. It is, however, possible to create a repetition operating on
163 /// an empty sub-expression. For example, `()*` is still considered valid.
164RepetitionMissing,
165/// The special word boundary syntax, `\b{something}`, was used, but
166 /// either EOF without `}` was seen, or an invalid character in the
167 /// braces was seen.
168SpecialWordBoundaryUnclosed,
169/// The special word boundary syntax, `\b{something}`, was used, but
170 /// `something` was not recognized as a valid word boundary kind.
171SpecialWordBoundaryUnrecognized,
172/// The syntax `\b{` was observed, but afterwards the end of the pattern
173 /// was observed without being able to tell whether it was meant to be a
174 /// bounded repetition on the `\b` or the beginning of a special word
175 /// boundary assertion.
176SpecialWordOrRepetitionUnexpectedEof,
177/// The Unicode class is not valid. This typically occurs when a `\p` is
178 /// followed by something other than a `{`.
179UnicodeClassInvalid,
180/// When octal support is disabled, this error is produced when an octal
181 /// escape is used. The octal escape is assumed to be an invocation of
182 /// a backreference, which is the common case.
183UnsupportedBackreference,
184/// When syntax similar to PCRE's look-around is used, this error is
185 /// returned. Some example syntaxes that are rejected include, but are
186 /// not necessarily limited to, `(?=re)`, `(?!re)`, `(?<=re)` and
187 /// `(?<!re)`. Note that all of these syntaxes are otherwise invalid; this
188 /// error is used to improve the user experience.
189UnsupportedLookAround,
190}
191192#[cfg(feature = "std")]
193impl std::error::Errorfor Error {}
194195impl core::fmt::Displayfor Error {
196fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
197crate::error::Formatter::from(self).fmt(f)
198 }
199}
200201impl core::fmt::Displayfor ErrorKind {
202fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
203use self::ErrorKind::*;
204match *self {
205CaptureLimitExceeded => f.write_fmt(format_args!("exceeded the maximum number of capturing groups ({0})",
u32::MAX))write!(
206f,
207"exceeded the maximum number of \
208 capturing groups ({})",
209 u32::MAX
210 ),
211ClassEscapeInvalid => {
212f.write_fmt(format_args!("invalid escape sequence found in character class"))write!(f, "invalid escape sequence found in character class")213 }
214ClassRangeInvalid => f.write_fmt(format_args!("invalid character class range, the start must be <= the end"))write!(
215f,
216"invalid character class range, \
217 the start must be <= the end"
218),
219ClassRangeLiteral => {
220f.write_fmt(format_args!("invalid range boundary, must be a literal"))write!(f, "invalid range boundary, must be a literal")221 }
222ClassUnclosed => f.write_fmt(format_args!("unclosed character class"))write!(f, "unclosed character class"),
223DecimalEmpty => f.write_fmt(format_args!("decimal literal empty"))write!(f, "decimal literal empty"),
224DecimalInvalid => f.write_fmt(format_args!("decimal literal invalid"))write!(f, "decimal literal invalid"),
225EscapeHexEmpty => f.write_fmt(format_args!("hexadecimal literal empty"))write!(f, "hexadecimal literal empty"),
226EscapeHexInvalid => {
227f.write_fmt(format_args!("hexadecimal literal is not a Unicode scalar value"))write!(f, "hexadecimal literal is not a Unicode scalar value")228 }
229EscapeHexInvalidDigit => f.write_fmt(format_args!("invalid hexadecimal digit"))write!(f, "invalid hexadecimal digit"),
230EscapeUnexpectedEof => f.write_fmt(format_args!("incomplete escape sequence, reached end of pattern prematurely"))write!(
231f,
232"incomplete escape sequence, \
233 reached end of pattern prematurely"
234),
235EscapeUnrecognized => f.write_fmt(format_args!("unrecognized escape sequence"))write!(f, "unrecognized escape sequence"),
236FlagDanglingNegation => {
237f.write_fmt(format_args!("dangling flag negation operator"))write!(f, "dangling flag negation operator")238 }
239FlagDuplicate { .. } => f.write_fmt(format_args!("duplicate flag"))write!(f, "duplicate flag"),
240FlagRepeatedNegation { .. } => {
241f.write_fmt(format_args!("flag negation operator repeated"))write!(f, "flag negation operator repeated")242 }
243FlagUnexpectedEof => {
244f.write_fmt(format_args!("expected flag but got end of regex"))write!(f, "expected flag but got end of regex")245 }
246FlagUnrecognized => f.write_fmt(format_args!("unrecognized flag"))write!(f, "unrecognized flag"),
247GroupNameDuplicate { .. } => {
248f.write_fmt(format_args!("duplicate capture group name"))write!(f, "duplicate capture group name")249 }
250GroupNameEmpty => f.write_fmt(format_args!("empty capture group name"))write!(f, "empty capture group name"),
251GroupNameInvalid => f.write_fmt(format_args!("invalid capture group character"))write!(f, "invalid capture group character"),
252GroupNameUnexpectedEof => f.write_fmt(format_args!("unclosed capture group name"))write!(f, "unclosed capture group name"),
253GroupUnclosed => f.write_fmt(format_args!("unclosed group"))write!(f, "unclosed group"),
254GroupUnopened => f.write_fmt(format_args!("unopened group"))write!(f, "unopened group"),
255NestLimitExceeded(limit) => f.write_fmt(format_args!("exceed the maximum number of nested parentheses/brackets ({0})",
limit))write!(
256f,
257"exceed the maximum number of \
258 nested parentheses/brackets ({})",
259 limit
260 ),
261RepetitionCountInvalid => f.write_fmt(format_args!("invalid repetition count range, the start must be <= the end"))write!(
262f,
263"invalid repetition count range, \
264 the start must be <= the end"
265),
266RepetitionCountDecimalEmpty => {
267f.write_fmt(format_args!("repetition quantifier expects a valid decimal"))write!(f, "repetition quantifier expects a valid decimal")268 }
269RepetitionCountUnclosed => {
270f.write_fmt(format_args!("unclosed counted repetition"))write!(f, "unclosed counted repetition")271 }
272RepetitionMissing => {
273f.write_fmt(format_args!("repetition operator missing expression"))write!(f, "repetition operator missing expression")274 }
275SpecialWordBoundaryUnclosed => {
276f.write_fmt(format_args!("special word boundary assertion is either unclosed or contains an invalid character"))write!(
277f,
278"special word boundary assertion is either \
279 unclosed or contains an invalid character",
280 )281 }
282SpecialWordBoundaryUnrecognized => {
283f.write_fmt(format_args!("unrecognized special word boundary assertion, valid choices are: start, end, start-half or end-half"))write!(
284f,
285"unrecognized special word boundary assertion, \
286 valid choices are: start, end, start-half \
287 or end-half",
288 )289 }
290SpecialWordOrRepetitionUnexpectedEof => {
291f.write_fmt(format_args!("found either the beginning of a special word boundary or a bounded repetition on a \\b with an opening brace, but no closing brace"))write!(
292f,
293"found either the beginning of a special word \
294 boundary or a bounded repetition on a \\b with \
295 an opening brace, but no closing brace",
296 )297 }
298UnicodeClassInvalid => {
299f.write_fmt(format_args!("invalid Unicode character class"))write!(f, "invalid Unicode character class")300 }
301UnsupportedBackreference => {
302f.write_fmt(format_args!("backreferences are not supported"))write!(f, "backreferences are not supported")303 }
304UnsupportedLookAround => f.write_fmt(format_args!("look-around, including look-ahead and look-behind, is not supported"))write!(
305f,
306"look-around, including look-ahead and look-behind, \
307 is not supported"
308),
309 }
310 }
311}
312313/// Span represents the position information of a single AST item.
314///
315/// All span positions are absolute byte offsets that can be used on the
316/// original regular expression that was parsed.
317#[derive(#[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for Span {
}
#[automatically_derived]impl ::core::clone::Clone for Span {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<Position>;
*self
}
}Clone, #[automatically_derived]impl ::core::marker::Copy for Span { }Copy, #[automatically_derived]impl ::core::cmp::Eq for Span {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Position>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for Span { }
#[automatically_derived]impl ::core::cmp::PartialEq for Span {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.start == other.start && self.end == other.end
}
}PartialEq)]
318#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
319pub struct Span {
320/// The start byte offset.
321pub start: Position,
322/// The end byte offset.
323pub end: Position,
324}
325326impl core::fmt::Debugfor Span {
327fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
328f.write_fmt(format_args!("Span({0:?}, {1:?})", self.start, self.end))write!(f, "Span({:?}, {:?})", self.start, self.end)329 }
330}
331332impl Ordfor Span {
333fn cmp(&self, other: &Span) -> Ordering {
334 (&self.start, &self.end).cmp(&(&other.start, &other.end))
335 }
336}
337338impl PartialOrdfor Span {
339fn partial_cmp(&self, other: &Span) -> Option<Ordering> {
340Some(self.cmp(other))
341 }
342}
343344/// A single position in a regular expression.
345///
346/// A position encodes one half of a span, and include the byte offset, line
347/// number and column number.
348#[derive(#[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for Position {
}
#[automatically_derived]impl ::core::clone::Clone for Position {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<usize>;
*self
}
}Clone, #[automatically_derived]impl ::core::marker::Copy for Position { }Copy, #[automatically_derived]impl ::core::cmp::Eq for Position {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<usize>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for Position
{
}
#[automatically_derived]impl ::core::cmp::PartialEq for Position {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.offset == other.offset && self.line == other.line &&
self.column == other.column
}
}PartialEq)]
349#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
350pub struct Position {
351/// The absolute offset of this position, starting at `0` from the
352 /// beginning of the regular expression pattern string.
353pub offset: usize,
354/// The line number, starting at `1`.
355pub line: usize,
356/// The approximate column number, starting at `1`.
357pub column: usize,
358}
359360impl core::fmt::Debugfor Position {
361fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
362f.write_fmt(format_args!("Position(o: {0:?}, l: {1:?}, c: {2:?})",
self.offset, self.line, self.column))write!(
363f,
364"Position(o: {:?}, l: {:?}, c: {:?})",
365self.offset, self.line, self.column
366 )367 }
368}
369370impl Ordfor Position {
371fn cmp(&self, other: &Position) -> Ordering {
372self.offset.cmp(&other.offset)
373 }
374}
375376impl PartialOrdfor Position {
377fn partial_cmp(&self, other: &Position) -> Option<Ordering> {
378Some(self.cmp(other))
379 }
380}
381382impl Span {
383/// Create a new span with the given positions.
384pub fn new(start: Position, end: Position) -> Span {
385Span { start, end }
386 }
387388/// Create a new span using the given position as the start and end.
389pub fn splat(pos: Position) -> Span {
390Span::new(pos, pos)
391 }
392393/// Create a new span by replacing the starting the position with the one
394 /// given.
395pub fn with_start(self, pos: Position) -> Span {
396Span { start: pos, ..self }
397 }
398399/// Create a new span by replacing the ending the position with the one
400 /// given.
401pub fn with_end(self, pos: Position) -> Span {
402Span { end: pos, ..self }
403 }
404405/// Returns true if and only if this span occurs on a single line.
406pub fn is_one_line(&self) -> bool {
407self.start.line == self.end.line
408 }
409410/// Returns true if and only if this span is empty. That is, it points to
411 /// a single position in the concrete syntax of a regular expression.
412pub fn is_empty(&self) -> bool {
413self.start.offset == self.end.offset
414 }
415}
416417impl Position {
418/// Create a new position with the given information.
419 ///
420 /// `offset` is the absolute offset of the position, starting at `0` from
421 /// the beginning of the regular expression pattern string.
422 ///
423 /// `line` is the line number, starting at `1`.
424 ///
425 /// `column` is the approximate column number, starting at `1`.
426pub fn new(offset: usize, line: usize, column: usize) -> Position {
427Position { offset, line, column }
428 }
429}
430431/// An abstract syntax tree for a singular expression along with comments
432/// found.
433///
434/// Comments are not stored in the tree itself to avoid complexity. Each
435/// comment contains a span of precisely where it occurred in the original
436/// regular expression.
437#[derive(#[automatically_derived]impl ::core::clone::Clone for WithComments {
#[inline]
fn clone(&self) -> Self {
WithComments {
ast: ::core::clone::Clone::clone(&self.ast),
comments: ::core::clone::Clone::clone(&self.comments),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for WithComments {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"WithComments ast comments", &self.ast, &&self.comments)
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for WithComments {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Ast>;
let _: ::core::cmp::AssertParamIsEq<Vec<Comment>>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
WithComments {
}
#[automatically_derived]impl ::core::cmp::PartialEq for WithComments {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.ast == other.ast && self.comments == other.comments
}
}PartialEq)]
438#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
439pub struct WithComments {
440/// The actual ast.
441pub ast: Ast,
442/// All comments found in the original regular expression.
443pub comments: Vec<Comment>,
444}
445446/// A comment from a regular expression with an associated span.
447///
448/// A regular expression can only contain comments when the `x` flag is
449/// enabled.
450#[derive(#[automatically_derived]impl ::core::clone::Clone for Comment {
#[inline]
fn clone(&self) -> Self {
Comment {
span: ::core::clone::Clone::clone(&self.span),
comment: ::core::clone::Clone::clone(&self.comment),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for Comment {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"Comment span comment", &self.span, &&self.comment)
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for Comment {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Span>;
let _: ::core::cmp::AssertParamIsEq<String>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for Comment {
}
#[automatically_derived]impl ::core::cmp::PartialEq for Comment {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.span == other.span && self.comment == other.comment
}
}PartialEq)]
451#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
452pub struct Comment {
453/// The span of this comment, including the beginning `#` and ending `\n`.
454pub span: Span,
455/// The comment text, starting with the first character following the `#`
456 /// and ending with the last character preceding the `\n`.
457pub comment: String,
458}
459460/// An abstract syntax tree for a single regular expression.
461///
462/// An `Ast`'s `fmt::Display` implementation uses constant stack space and heap
463/// space proportional to the size of the `Ast`.
464///
465/// This type defines its own destructor that uses constant stack space and
466/// heap space proportional to the size of the `Ast`.
467#[derive(#[automatically_derived]impl ::core::clone::Clone for Ast {
#[inline]
fn clone(&self) -> Self {
match self {
Self::Empty(__self_0) =>
Ast::Empty(::core::clone::Clone::clone(__self_0)),
Self::Flags(__self_0) =>
Ast::Flags(::core::clone::Clone::clone(__self_0)),
Self::Literal(__self_0) =>
Ast::Literal(::core::clone::Clone::clone(__self_0)),
Self::Dot(__self_0) =>
Ast::Dot(::core::clone::Clone::clone(__self_0)),
Self::Assertion(__self_0) =>
Ast::Assertion(::core::clone::Clone::clone(__self_0)),
Self::ClassUnicode(__self_0) =>
Ast::ClassUnicode(::core::clone::Clone::clone(__self_0)),
Self::ClassPerl(__self_0) =>
Ast::ClassPerl(::core::clone::Clone::clone(__self_0)),
Self::ClassBracketed(__self_0) =>
Ast::ClassBracketed(::core::clone::Clone::clone(__self_0)),
Self::Repetition(__self_0) =>
Ast::Repetition(::core::clone::Clone::clone(__self_0)),
Self::Group(__self_0) =>
Ast::Group(::core::clone::Clone::clone(__self_0)),
Self::Alternation(__self_0) =>
Ast::Alternation(::core::clone::Clone::clone(__self_0)),
Self::Concat(__self_0) =>
Ast::Concat(::core::clone::Clone::clone(__self_0)),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for Ast {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Self::Empty(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f, "Empty",
&__self_0),
Self::Flags(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f, "Flags",
&__self_0),
Self::Literal(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"Literal", &__self_0),
Self::Dot(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f, "Dot",
&__self_0),
Self::Assertion(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"Assertion", &__self_0),
Self::ClassUnicode(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"ClassUnicode", &__self_0),
Self::ClassPerl(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"ClassPerl", &__self_0),
Self::ClassBracketed(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"ClassBracketed", &__self_0),
Self::Repetition(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"Repetition", &__self_0),
Self::Group(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f, "Group",
&__self_0),
Self::Alternation(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"Alternation", &__self_0),
Self::Concat(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"Concat", &__self_0),
}
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for Ast {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Box<Span>>;
let _: ::core::cmp::AssertParamIsEq<Box<SetFlags>>;
let _: ::core::cmp::AssertParamIsEq<Box<Literal>>;
let _: ::core::cmp::AssertParamIsEq<Box<Span>>;
let _: ::core::cmp::AssertParamIsEq<Box<Assertion>>;
let _: ::core::cmp::AssertParamIsEq<Box<ClassUnicode>>;
let _: ::core::cmp::AssertParamIsEq<Box<ClassPerl>>;
let _: ::core::cmp::AssertParamIsEq<Box<ClassBracketed>>;
let _: ::core::cmp::AssertParamIsEq<Box<Repetition>>;
let _: ::core::cmp::AssertParamIsEq<Box<Group>>;
let _: ::core::cmp::AssertParamIsEq<Box<Alternation>>;
let _: ::core::cmp::AssertParamIsEq<Box<Concat>>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for Ast { }
#[automatically_derived]impl ::core::cmp::PartialEq for Ast {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other) &&
match (self, other) {
(Self::Empty(__self_0), Self::Empty(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::Flags(__self_0), Self::Flags(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::Literal(__self_0), Self::Literal(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::Dot(__self_0), Self::Dot(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::Assertion(__self_0), Self::Assertion(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::ClassUnicode(__self_0), Self::ClassUnicode(__arg1_0))
=> __self_0 == __arg1_0,
(Self::ClassPerl(__self_0), Self::ClassPerl(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::ClassBracketed(__self_0),
Self::ClassBracketed(__arg1_0)) => __self_0 == __arg1_0,
(Self::Repetition(__self_0), Self::Repetition(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::Group(__self_0), Self::Group(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::Alternation(__self_0), Self::Alternation(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::Concat(__self_0), Self::Concat(__arg1_0)) =>
__self_0 == __arg1_0,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq)]
468#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
469pub enum Ast {
470/// An empty regex that matches everything.
471Empty(Box<Span>),
472/// A set of flags, e.g., `(?is)`.
473Flags(Box<SetFlags>),
474/// A single character literal, which includes escape sequences.
475Literal(Box<Literal>),
476/// The "any character" class.
477Dot(Box<Span>),
478/// A single zero-width assertion.
479Assertion(Box<Assertion>),
480/// A single Unicode character class, e.g., `\pL` or `\p{Greek}`.
481ClassUnicode(Box<ClassUnicode>),
482/// A single perl character class, e.g., `\d` or `\W`.
483ClassPerl(Box<ClassPerl>),
484/// A single bracketed character class set, which may contain zero or more
485 /// character ranges and/or zero or more nested classes. e.g.,
486 /// `[a-zA-Z\pL]`.
487ClassBracketed(Box<ClassBracketed>),
488/// A repetition operator applied to an arbitrary regular expression.
489Repetition(Box<Repetition>),
490/// A grouped regular expression.
491Group(Box<Group>),
492/// An alternation of regular expressions.
493Alternation(Box<Alternation>),
494/// A concatenation of regular expressions.
495Concat(Box<Concat>),
496}
497498impl Ast {
499/// Create an "empty" AST item.
500pub fn empty(span: Span) -> Ast {
501 Ast::Empty(Box::new(span))
502 }
503504/// Create a "flags" AST item.
505pub fn flags(e: SetFlags) -> Ast {
506 Ast::Flags(Box::new(e))
507 }
508509/// Create a "literal" AST item.
510pub fn literal(e: Literal) -> Ast {
511 Ast::Literal(Box::new(e))
512 }
513514/// Create a "dot" AST item.
515pub fn dot(span: Span) -> Ast {
516 Ast::Dot(Box::new(span))
517 }
518519/// Create a "assertion" AST item.
520pub fn assertion(e: Assertion) -> Ast {
521 Ast::Assertion(Box::new(e))
522 }
523524/// Create a "Unicode class" AST item.
525pub fn class_unicode(e: ClassUnicode) -> Ast {
526 Ast::ClassUnicode(Box::new(e))
527 }
528529/// Create a "Perl class" AST item.
530pub fn class_perl(e: ClassPerl) -> Ast {
531 Ast::ClassPerl(Box::new(e))
532 }
533534/// Create a "bracketed class" AST item.
535pub fn class_bracketed(e: ClassBracketed) -> Ast {
536 Ast::ClassBracketed(Box::new(e))
537 }
538539/// Create a "repetition" AST item.
540pub fn repetition(e: Repetition) -> Ast {
541 Ast::Repetition(Box::new(e))
542 }
543544/// Create a "group" AST item.
545pub fn group(e: Group) -> Ast {
546 Ast::Group(Box::new(e))
547 }
548549/// Create a "alternation" AST item.
550pub fn alternation(e: Alternation) -> Ast {
551 Ast::Alternation(Box::new(e))
552 }
553554/// Create a "concat" AST item.
555pub fn concat(e: Concat) -> Ast {
556 Ast::Concat(Box::new(e))
557 }
558559/// Return the span of this abstract syntax tree.
560pub fn span(&self) -> &Span {
561match *self {
562 Ast::Empty(ref span) => span,
563 Ast::Flags(ref x) => &x.span,
564 Ast::Literal(ref x) => &x.span,
565 Ast::Dot(ref span) => span,
566 Ast::Assertion(ref x) => &x.span,
567 Ast::ClassUnicode(ref x) => &x.span,
568 Ast::ClassPerl(ref x) => &x.span,
569 Ast::ClassBracketed(ref x) => &x.span,
570 Ast::Repetition(ref x) => &x.span,
571 Ast::Group(ref x) => &x.span,
572 Ast::Alternation(ref x) => &x.span,
573 Ast::Concat(ref x) => &x.span,
574 }
575 }
576577/// Return true if and only if this Ast is empty.
578pub fn is_empty(&self) -> bool {
579match *self {
580 Ast::Empty(_) => true,
581_ => false,
582 }
583 }
584585/// Returns true if and only if this AST has any (including possibly empty)
586 /// subexpressions.
587fn has_subexprs(&self) -> bool {
588match *self {
589 Ast::Empty(_)
590 | Ast::Flags(_)
591 | Ast::Literal(_)
592 | Ast::Dot(_)
593 | Ast::Assertion(_)
594 | Ast::ClassUnicode(_)
595 | Ast::ClassPerl(_) => false,
596 Ast::ClassBracketed(_)
597 | Ast::Repetition(_)
598 | Ast::Group(_)
599 | Ast::Alternation(_)
600 | Ast::Concat(_) => true,
601 }
602 }
603}
604605/// Print a display representation of this Ast.
606///
607/// This does not preserve any of the original whitespace formatting that may
608/// have originally been present in the concrete syntax from which this Ast
609/// was generated.
610///
611/// This implementation uses constant stack space and heap space proportional
612/// to the size of the `Ast`.
613impl core::fmt::Displayfor Ast {
614fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
615use crate::ast::print::Printer;
616Printer::new().print(self, f)
617 }
618}
619620/// An alternation of regular expressions.
621#[derive(#[automatically_derived]impl ::core::clone::Clone for Alternation {
#[inline]
fn clone(&self) -> Self {
Alternation {
span: ::core::clone::Clone::clone(&self.span),
asts: ::core::clone::Clone::clone(&self.asts),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for Alternation {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"Alternation span asts", &self.span, &&self.asts)
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for Alternation {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Span>;
let _: ::core::cmp::AssertParamIsEq<Vec<Ast>>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
Alternation {
}
#[automatically_derived]impl ::core::cmp::PartialEq for Alternation {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.span == other.span && self.asts == other.asts
}
}PartialEq)]
622#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
623pub struct Alternation {
624/// The span of this alternation.
625pub span: Span,
626/// The alternate regular expressions.
627pub asts: Vec<Ast>,
628}
629630impl Alternation {
631/// Return this alternation as an AST.
632 ///
633 /// If this alternation contains zero ASTs, then `Ast::empty` is returned.
634 /// If this alternation contains exactly 1 AST, then the corresponding AST
635 /// is returned. Otherwise, `Ast::alternation` is returned.
636pub fn into_ast(mut self) -> Ast {
637match self.asts.len() {
6380 => Ast::empty(self.span),
6391 => self.asts.pop().unwrap(),
640_ => Ast::alternation(self),
641 }
642 }
643}
644645/// A concatenation of regular expressions.
646#[derive(#[automatically_derived]impl ::core::clone::Clone for Concat {
#[inline]
fn clone(&self) -> Self {
Concat {
span: ::core::clone::Clone::clone(&self.span),
asts: ::core::clone::Clone::clone(&self.asts),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for Concat {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"Concat span asts", &self.span, &&self.asts)
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for Concat {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Span>;
let _: ::core::cmp::AssertParamIsEq<Vec<Ast>>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for Concat {
}
#[automatically_derived]impl ::core::cmp::PartialEq for Concat {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.span == other.span && self.asts == other.asts
}
}PartialEq)]
647#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
648pub struct Concat {
649/// The span of this concatenation.
650pub span: Span,
651/// The concatenation regular expressions.
652pub asts: Vec<Ast>,
653}
654655impl Concat {
656/// Return this concatenation as an AST.
657 ///
658 /// If this alternation contains zero ASTs, then `Ast::empty` is returned.
659 /// If this alternation contains exactly 1 AST, then the corresponding AST
660 /// is returned. Otherwise, `Ast::concat` is returned.
661pub fn into_ast(mut self) -> Ast {
662match self.asts.len() {
6630 => Ast::empty(self.span),
6641 => self.asts.pop().unwrap(),
665_ => Ast::concat(self),
666 }
667 }
668}
669670/// A single literal expression.
671///
672/// A literal corresponds to a single Unicode scalar value. Literals may be
673/// represented in their literal form, e.g., `a` or in their escaped form,
674/// e.g., `\x61`.
675#[derive(#[automatically_derived]impl ::core::clone::Clone for Literal {
#[inline]
fn clone(&self) -> Self {
Literal {
span: ::core::clone::Clone::clone(&self.span),
kind: ::core::clone::Clone::clone(&self.kind),
c: ::core::clone::Clone::clone(&self.c),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for Literal {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f,
"Literal span kind c", &self.span, &self.kind, &&self.c)
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for Literal {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Span>;
let _: ::core::cmp::AssertParamIsEq<LiteralKind>;
let _: ::core::cmp::AssertParamIsEq<char>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for Literal {
}
#[automatically_derived]impl ::core::cmp::PartialEq for Literal {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.c == other.c && self.span == other.span &&
self.kind == other.kind
}
}PartialEq)]
676#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
677pub struct Literal {
678/// The span of this literal.
679pub span: Span,
680/// The kind of this literal.
681pub kind: LiteralKind,
682/// The Unicode scalar value corresponding to this literal.
683pub c: char,
684}
685686impl Literal {
687/// If this literal was written as a `\x` hex escape, then this returns
688 /// the corresponding byte value. Otherwise, this returns `None`.
689pub fn byte(&self) -> Option<u8> {
690match self.kind {
691 LiteralKind::HexFixed(HexLiteralKind::X) => {
692u8::try_from(self.c).ok()
693 }
694_ => None,
695 }
696 }
697}
698699/// The kind of a single literal expression.
700#[derive(#[automatically_derived]impl ::core::clone::Clone for LiteralKind {
#[inline]
fn clone(&self) -> Self {
match self {
Self::Verbatim => LiteralKind::Verbatim,
Self::Meta => LiteralKind::Meta,
Self::Superfluous => LiteralKind::Superfluous,
Self::Octal => LiteralKind::Octal,
Self::HexFixed(__self_0) =>
LiteralKind::HexFixed(::core::clone::Clone::clone(__self_0)),
Self::HexBrace(__self_0) =>
LiteralKind::HexBrace(::core::clone::Clone::clone(__self_0)),
Self::Special(__self_0) =>
LiteralKind::Special(::core::clone::Clone::clone(__self_0)),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for LiteralKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Self::Verbatim =>
::core::fmt::Formatter::write_str(f, "Verbatim"),
Self::Meta => ::core::fmt::Formatter::write_str(f, "Meta"),
Self::Superfluous =>
::core::fmt::Formatter::write_str(f, "Superfluous"),
Self::Octal => ::core::fmt::Formatter::write_str(f, "Octal"),
Self::HexFixed(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"HexFixed", &__self_0),
Self::HexBrace(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"HexBrace", &__self_0),
Self::Special(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"Special", &__self_0),
}
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for LiteralKind {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<HexLiteralKind>;
let _: ::core::cmp::AssertParamIsEq<SpecialLiteralKind>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
LiteralKind {
}
#[automatically_derived]impl ::core::cmp::PartialEq for LiteralKind {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other) &&
match (self, other) {
(Self::HexFixed(__self_0), Self::HexFixed(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::HexBrace(__self_0), Self::HexBrace(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::Special(__self_0), Self::Special(__arg1_0)) =>
__self_0 == __arg1_0,
_ => true,
}
}
}PartialEq)]
701#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
702pub enum LiteralKind {
703/// The literal is written verbatim, e.g., `a` or `☃`.
704Verbatim,
705/// The literal is written as an escape because it is otherwise a special
706 /// regex meta character, e.g., `\*` or `\[`.
707Meta,
708/// The literal is written as an escape despite the fact that the escape is
709 /// unnecessary, e.g., `\%` or `\/`.
710Superfluous,
711/// The literal is written as an octal escape, e.g., `\141`.
712Octal,
713/// The literal is written as a hex code with a fixed number of digits
714 /// depending on the type of the escape, e.g., `\x61` or `\u0061` or
715 /// `\U00000061`.
716HexFixed(HexLiteralKind),
717/// The literal is written as a hex code with a bracketed number of
718 /// digits. The only restriction is that the bracketed hex code must refer
719 /// to a valid Unicode scalar value.
720HexBrace(HexLiteralKind),
721/// The literal is written as a specially recognized escape, e.g., `\f`
722 /// or `\n`.
723Special(SpecialLiteralKind),
724}
725726/// The type of a special literal.
727///
728/// A special literal is a special escape sequence recognized by the regex
729/// parser, e.g., `\f` or `\n`.
730#[derive(#[automatically_derived]impl ::core::clone::Clone for SpecialLiteralKind {
#[inline]
fn clone(&self) -> Self {
match self {
Self::Bell => SpecialLiteralKind::Bell,
Self::FormFeed => SpecialLiteralKind::FormFeed,
Self::Tab => SpecialLiteralKind::Tab,
Self::LineFeed => SpecialLiteralKind::LineFeed,
Self::CarriageReturn => SpecialLiteralKind::CarriageReturn,
Self::VerticalTab => SpecialLiteralKind::VerticalTab,
Self::Space => SpecialLiteralKind::Space,
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for SpecialLiteralKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_c_like_enum_write_str(f,
"Bell FormFeed Tab LineFeed CarriageReturn VerticalTab Space",
match self {
SpecialLiteralKind::Bell => 0usize,
SpecialLiteralKind::FormFeed => 5usize,
SpecialLiteralKind::Tab => 14usize,
SpecialLiteralKind::LineFeed => 18usize,
SpecialLiteralKind::CarriageReturn => 27usize,
SpecialLiteralKind::VerticalTab => 42usize,
SpecialLiteralKind::Space => 54usize,
})
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for SpecialLiteralKind { }Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
SpecialLiteralKind {
}
#[automatically_derived]impl ::core::cmp::PartialEq for SpecialLiteralKind {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other)
}
}PartialEq)]
731#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
732pub enum SpecialLiteralKind {
733/// Bell, spelled `\a` (`\x07`).
734Bell,
735/// Form feed, spelled `\f` (`\x0C`).
736FormFeed,
737/// Tab, spelled `\t` (`\x09`).
738Tab,
739/// Line feed, spelled `\n` (`\x0A`).
740LineFeed,
741/// Carriage return, spelled `\r` (`\x0D`).
742CarriageReturn,
743/// Vertical tab, spelled `\v` (`\x0B`).
744VerticalTab,
745/// Space, spelled `\ ` (`\x20`). Note that this can only appear when
746 /// parsing in verbose mode.
747Space,
748}
749750/// The type of a Unicode hex literal.
751///
752/// Note that all variants behave the same when used with brackets. They only
753/// differ when used without brackets in the number of hex digits that must
754/// follow.
755#[derive(#[automatically_derived]impl ::core::clone::Clone for HexLiteralKind {
#[inline]
fn clone(&self) -> Self {
match self {
Self::X => HexLiteralKind::X,
Self::UnicodeShort => HexLiteralKind::UnicodeShort,
Self::UnicodeLong => HexLiteralKind::UnicodeLong,
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for HexLiteralKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
HexLiteralKind::X => "X",
HexLiteralKind::UnicodeShort => "UnicodeShort",
HexLiteralKind::UnicodeLong => "UnicodeLong",
})
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for HexLiteralKind { }Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
HexLiteralKind {
}
#[automatically_derived]impl ::core::cmp::PartialEq for HexLiteralKind {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other)
}
}PartialEq)]
756#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
757pub enum HexLiteralKind {
758/// A `\x` prefix. When used without brackets, this form is limited to
759 /// two digits.
760X,
761/// A `\u` prefix. When used without brackets, this form is limited to
762 /// four digits.
763UnicodeShort,
764/// A `\U` prefix. When used without brackets, this form is limited to
765 /// eight digits.
766UnicodeLong,
767}
768769impl HexLiteralKind {
770/// The number of digits that must be used with this literal form when
771 /// used without brackets. When used with brackets, there is no
772 /// restriction on the number of digits.
773pub fn digits(&self) -> u32 {
774match *self {
775 HexLiteralKind::X => 2,
776 HexLiteralKind::UnicodeShort => 4,
777 HexLiteralKind::UnicodeLong => 8,
778 }
779 }
780}
781782/// A Perl character class.
783#[derive(#[automatically_derived]impl ::core::clone::Clone for ClassPerl {
#[inline]
fn clone(&self) -> Self {
ClassPerl {
span: ::core::clone::Clone::clone(&self.span),
kind: ::core::clone::Clone::clone(&self.kind),
negated: ::core::clone::Clone::clone(&self.negated),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for ClassPerl {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f,
"ClassPerl span kind negated", &self.span, &self.kind,
&&self.negated)
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for ClassPerl {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Span>;
let _: ::core::cmp::AssertParamIsEq<ClassPerlKind>;
let _: ::core::cmp::AssertParamIsEq<bool>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for ClassPerl
{
}
#[automatically_derived]impl ::core::cmp::PartialEq for ClassPerl {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.negated == other.negated && self.span == other.span &&
self.kind == other.kind
}
}PartialEq)]
784#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
785pub struct ClassPerl {
786/// The span of this class.
787pub span: Span,
788/// The kind of Perl class.
789pub kind: ClassPerlKind,
790/// Whether the class is negated or not. e.g., `\d` is not negated but
791 /// `\D` is.
792pub negated: bool,
793}
794795/// The available Perl character classes.
796#[derive(#[automatically_derived]impl ::core::clone::Clone for ClassPerlKind {
#[inline]
fn clone(&self) -> Self {
match self {
Self::Digit => ClassPerlKind::Digit,
Self::Space => ClassPerlKind::Space,
Self::Word => ClassPerlKind::Word,
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for ClassPerlKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
ClassPerlKind::Digit => "Digit",
ClassPerlKind::Space => "Space",
ClassPerlKind::Word => "Word",
})
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for ClassPerlKind { }Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
ClassPerlKind {
}
#[automatically_derived]impl ::core::cmp::PartialEq for ClassPerlKind {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other)
}
}PartialEq)]
797#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
798pub enum ClassPerlKind {
799/// Decimal numbers.
800Digit,
801/// Whitespace.
802Space,
803/// Word characters.
804Word,
805}
806807/// An ASCII character class.
808#[derive(#[automatically_derived]impl ::core::clone::Clone for ClassAscii {
#[inline]
fn clone(&self) -> Self {
ClassAscii {
span: ::core::clone::Clone::clone(&self.span),
kind: ::core::clone::Clone::clone(&self.kind),
negated: ::core::clone::Clone::clone(&self.negated),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for ClassAscii {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f,
"ClassAscii span kind negated", &self.span, &self.kind,
&&self.negated)
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for ClassAscii {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Span>;
let _: ::core::cmp::AssertParamIsEq<ClassAsciiKind>;
let _: ::core::cmp::AssertParamIsEq<bool>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
ClassAscii {
}
#[automatically_derived]impl ::core::cmp::PartialEq for ClassAscii {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.negated == other.negated && self.span == other.span &&
self.kind == other.kind
}
}PartialEq)]
809#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
810pub struct ClassAscii {
811/// The span of this class.
812pub span: Span,
813/// The kind of ASCII class.
814pub kind: ClassAsciiKind,
815/// Whether the class is negated or not. e.g., `[[:alpha:]]` is not negated
816 /// but `[[:^alpha:]]` is.
817pub negated: bool,
818}
819820/// The available ASCII character classes.
821#[derive(#[automatically_derived]impl ::core::clone::Clone for ClassAsciiKind {
#[inline]
fn clone(&self) -> Self {
match self {
Self::Alnum => ClassAsciiKind::Alnum,
Self::Alpha => ClassAsciiKind::Alpha,
Self::Ascii => ClassAsciiKind::Ascii,
Self::Blank => ClassAsciiKind::Blank,
Self::Cntrl => ClassAsciiKind::Cntrl,
Self::Digit => ClassAsciiKind::Digit,
Self::Graph => ClassAsciiKind::Graph,
Self::Lower => ClassAsciiKind::Lower,
Self::Print => ClassAsciiKind::Print,
Self::Punct => ClassAsciiKind::Punct,
Self::Space => ClassAsciiKind::Space,
Self::Upper => ClassAsciiKind::Upper,
Self::Word => ClassAsciiKind::Word,
Self::Xdigit => ClassAsciiKind::Xdigit,
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for ClassAsciiKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_c_like_enum_write_str(f,
"Alnum Alpha Ascii Blank Cntrl Digit Graph Lower Print Punct Space Upper Word Xdigit",
match self {
ClassAsciiKind::Alnum => 0usize,
ClassAsciiKind::Alpha => 6usize,
ClassAsciiKind::Ascii => 12usize,
ClassAsciiKind::Blank => 18usize,
ClassAsciiKind::Cntrl => 24usize,
ClassAsciiKind::Digit => 30usize,
ClassAsciiKind::Graph => 36usize,
ClassAsciiKind::Lower => 42usize,
ClassAsciiKind::Print => 48usize,
ClassAsciiKind::Punct => 54usize,
ClassAsciiKind::Space => 60usize,
ClassAsciiKind::Upper => 66usize,
ClassAsciiKind::Word => 72usize,
ClassAsciiKind::Xdigit => 77usize,
})
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for ClassAsciiKind { }Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
ClassAsciiKind {
}
#[automatically_derived]impl ::core::cmp::PartialEq for ClassAsciiKind {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other)
}
}PartialEq)]
822#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
823pub enum ClassAsciiKind {
824/// `[0-9A-Za-z]`
825Alnum,
826/// `[A-Za-z]`
827Alpha,
828/// `[\x00-\x7F]`
829Ascii,
830/// `[ \t]`
831Blank,
832/// `[\x00-\x1F\x7F]`
833Cntrl,
834/// `[0-9]`
835Digit,
836/// `[!-~]`
837Graph,
838/// `[a-z]`
839Lower,
840/// `[ -~]`
841Print,
842/// ``[!-/:-@\[-`{-~]``
843Punct,
844/// `[\t\n\v\f\r ]`
845Space,
846/// `[A-Z]`
847Upper,
848/// `[0-9A-Za-z_]`
849Word,
850/// `[0-9A-Fa-f]`
851Xdigit,
852}
853854impl ClassAsciiKind {
855/// Return the corresponding ClassAsciiKind variant for the given name.
856 ///
857 /// The name given should correspond to the lowercase version of the
858 /// variant name. e.g., `cntrl` is the name for `ClassAsciiKind::Cntrl`.
859 ///
860 /// If no variant with the corresponding name exists, then `None` is
861 /// returned.
862pub fn from_name(name: &str) -> Option<ClassAsciiKind> {
863use self::ClassAsciiKind::*;
864match name {
865"alnum" => Some(Alnum),
866"alpha" => Some(Alpha),
867"ascii" => Some(Ascii),
868"blank" => Some(Blank),
869"cntrl" => Some(Cntrl),
870"digit" => Some(Digit),
871"graph" => Some(Graph),
872"lower" => Some(Lower),
873"print" => Some(Print),
874"punct" => Some(Punct),
875"space" => Some(Space),
876"upper" => Some(Upper),
877"word" => Some(Word),
878"xdigit" => Some(Xdigit),
879_ => None,
880 }
881 }
882}
883884/// A Unicode character class.
885#[derive(#[automatically_derived]impl ::core::clone::Clone for ClassUnicode {
#[inline]
fn clone(&self) -> Self {
ClassUnicode {
span: ::core::clone::Clone::clone(&self.span),
negated: ::core::clone::Clone::clone(&self.negated),
kind: ::core::clone::Clone::clone(&self.kind),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for ClassUnicode {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f,
"ClassUnicode span negated kind", &self.span, &self.negated,
&&self.kind)
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for ClassUnicode {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Span>;
let _: ::core::cmp::AssertParamIsEq<bool>;
let _: ::core::cmp::AssertParamIsEq<ClassUnicodeKind>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
ClassUnicode {
}
#[automatically_derived]impl ::core::cmp::PartialEq for ClassUnicode {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.negated == other.negated && self.span == other.span &&
self.kind == other.kind
}
}PartialEq)]
886#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
887pub struct ClassUnicode {
888/// The span of this class.
889pub span: Span,
890/// Whether this class is negated or not.
891 ///
892 /// Note: be careful when using this attribute. This specifically refers
893 /// to whether the class is written as `\p` or `\P`, where the latter
894 /// is `negated = true`. However, it also possible to write something like
895 /// `\P{scx!=Katakana}` which is actually equivalent to
896 /// `\p{scx=Katakana}` and is therefore not actually negated even though
897 /// `negated = true` here. To test whether this class is truly negated
898 /// or not, use the `is_negated` method.
899pub negated: bool,
900/// The kind of Unicode class.
901pub kind: ClassUnicodeKind,
902}
903904impl ClassUnicode {
905/// Returns true if this class has been negated.
906 ///
907 /// Note that this takes the Unicode op into account, if it's present.
908 /// e.g., `is_negated` for `\P{scx!=Katakana}` will return `false`.
909pub fn is_negated(&self) -> bool {
910match self.kind {
911 ClassUnicodeKind::NamedValue {
912 op: ClassUnicodeOpKind::NotEqual,
913 ..
914 } => !self.negated,
915_ => self.negated,
916 }
917 }
918}
919920/// The available forms of Unicode character classes.
921#[derive(#[automatically_derived]impl ::core::clone::Clone for ClassUnicodeKind {
#[inline]
fn clone(&self) -> Self {
match self {
Self::OneLetter(__self_0) =>
ClassUnicodeKind::OneLetter(::core::clone::Clone::clone(__self_0)),
Self::Named(__self_0) =>
ClassUnicodeKind::Named(::core::clone::Clone::clone(__self_0)),
Self::NamedValue { op: __self_0, name: __self_1, value: __self_2 }
=>
ClassUnicodeKind::NamedValue {
op: ::core::clone::Clone::clone(__self_0),
name: ::core::clone::Clone::clone(__self_1),
value: ::core::clone::Clone::clone(__self_2),
},
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for ClassUnicodeKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Self::OneLetter(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"OneLetter", &__self_0),
Self::Named(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f, "Named",
&__self_0),
Self::NamedValue { op: __self_0, name: __self_1, value: __self_2 }
=>
::core::fmt::Formatter::debug_struct_field3_finish(f,
"NamedValue op name value", __self_0, __self_1, &__self_2),
}
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for ClassUnicodeKind {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<char>;
let _: ::core::cmp::AssertParamIsEq<String>;
let _: ::core::cmp::AssertParamIsEq<ClassUnicodeOpKind>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
ClassUnicodeKind {
}
#[automatically_derived]impl ::core::cmp::PartialEq for ClassUnicodeKind {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other) &&
match (self, other) {
(Self::OneLetter(__self_0), Self::OneLetter(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::Named(__self_0), Self::Named(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::NamedValue {
op: __self_0, name: __self_1, value: __self_2 },
Self::NamedValue {
op: __arg1_0, name: __arg1_1, value: __arg1_2 }) =>
__self_0 == __arg1_0 && __self_1 == __arg1_1 &&
__self_2 == __arg1_2,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq)]
922pub enum ClassUnicodeKind {
923/// A one letter abbreviated class, e.g., `\pN`.
924OneLetter(char),
925/// A binary property, general category or script. The string may be
926 /// empty.
927Named(String),
928/// A property name and an associated value.
929NamedValue {
930/// The type of Unicode op used to associate `name` with `value`.
931op: ClassUnicodeOpKind,
932/// The property name (which may be empty).
933name: String,
934/// The property value (which may be empty).
935value: String,
936 },
937}
938939#[cfg(feature = "arbitrary")]
940impl arbitrary::Arbitrary<'_> for ClassUnicodeKind {
941fn arbitrary(
942 u: &mut arbitrary::Unstructured,
943 ) -> arbitrary::Result<ClassUnicodeKind> {
944#[cfg(any(
945 feature = "unicode-age",
946 feature = "unicode-bool",
947 feature = "unicode-gencat",
948 feature = "unicode-perl",
949 feature = "unicode-script",
950 feature = "unicode-segment",
951 ))]
952{
953use alloc::string::ToString;
954955use super::unicode_tables::{
956 property_names::PROPERTY_NAMES,
957 property_values::PROPERTY_VALUES,
958 };
959960match u.choose_index(3)? {
9610 => {
962let all = PROPERTY_VALUES
963 .iter()
964 .flat_map(|e| e.1.iter())
965 .filter(|(name, _)| name.len() == 1)
966 .count();
967let idx = u.choose_index(all)?;
968let value = PROPERTY_VALUES
969 .iter()
970 .flat_map(|e| e.1.iter())
971 .take(idx + 1)
972 .last()
973 .unwrap()
974 .0
975.chars()
976 .next()
977 .unwrap();
978Ok(ClassUnicodeKind::OneLetter(value))
979 }
9801 => {
981let all = PROPERTY_VALUES
982 .iter()
983 .map(|e| e.1.len())
984 .sum::<usize>()
985 + PROPERTY_NAMES.len();
986let idx = u.choose_index(all)?;
987let name = PROPERTY_VALUES
988 .iter()
989 .flat_map(|e| e.1.iter())
990 .chain(PROPERTY_NAMES)
991 .map(|(_, e)| e)
992 .take(idx + 1)
993 .last()
994 .unwrap();
995Ok(ClassUnicodeKind::Named(name.to_string()))
996 }
9972 => {
998let all = PROPERTY_VALUES
999 .iter()
1000 .map(|e| e.1.len())
1001 .sum::<usize>();
1002let idx = u.choose_index(all)?;
1003let (prop, value) = PROPERTY_VALUES
1004 .iter()
1005 .flat_map(|e| {
1006 e.1.iter().map(|(_, value)| (e.0, value))
1007 })
1008 .take(idx + 1)
1009 .last()
1010 .unwrap();
1011Ok(ClassUnicodeKind::NamedValue {
1012 op: u.arbitrary()?,
1013 name: prop.to_string(),
1014 value: value.to_string(),
1015 })
1016 }
1017_ => unreachable!("index chosen is impossible"),
1018 }
1019 }
1020#[cfg(not(any(
1021 feature = "unicode-age",
1022 feature = "unicode-bool",
1023 feature = "unicode-gencat",
1024 feature = "unicode-perl",
1025 feature = "unicode-script",
1026 feature = "unicode-segment",
1027 )))]
1028{
1029match u.choose_index(3)? {
10300 => Ok(ClassUnicodeKind::OneLetter(u.arbitrary()?)),
10311 => Ok(ClassUnicodeKind::Named(u.arbitrary()?)),
10322 => Ok(ClassUnicodeKind::NamedValue {
1033 op: u.arbitrary()?,
1034 name: u.arbitrary()?,
1035 value: u.arbitrary()?,
1036 }),
1037_ => unreachable!("index chosen is impossible"),
1038 }
1039 }
1040 }
10411042fn size_hint(depth: usize) -> (usize, Option<usize>) {
1043#[cfg(any(
1044 feature = "unicode-age",
1045 feature = "unicode-bool",
1046 feature = "unicode-gencat",
1047 feature = "unicode-perl",
1048 feature = "unicode-script",
1049 feature = "unicode-segment",
1050 ))]
1051{
1052 arbitrary::size_hint::and_all(&[
1053 usize::size_hint(depth),
1054 usize::size_hint(depth),
1055 arbitrary::size_hint::or(
1056 (0, Some(0)),
1057 ClassUnicodeOpKind::size_hint(depth),
1058 ),
1059 ])
1060 }
1061#[cfg(not(any(
1062 feature = "unicode-age",
1063 feature = "unicode-bool",
1064 feature = "unicode-gencat",
1065 feature = "unicode-perl",
1066 feature = "unicode-script",
1067 feature = "unicode-segment",
1068 )))]
1069{
1070 arbitrary::size_hint::and(
1071 usize::size_hint(depth),
1072 arbitrary::size_hint::or_all(&[
1073 char::size_hint(depth),
1074 String::size_hint(depth),
1075 arbitrary::size_hint::and_all(&[
1076 String::size_hint(depth),
1077 String::size_hint(depth),
1078 ClassUnicodeOpKind::size_hint(depth),
1079 ]),
1080 ]),
1081 )
1082 }
1083 }
1084}
10851086/// The type of op used in a Unicode character class.
1087#[derive(#[automatically_derived]impl ::core::clone::Clone for ClassUnicodeOpKind {
#[inline]
fn clone(&self) -> Self {
match self {
Self::Equal => ClassUnicodeOpKind::Equal,
Self::Colon => ClassUnicodeOpKind::Colon,
Self::NotEqual => ClassUnicodeOpKind::NotEqual,
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for ClassUnicodeOpKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
ClassUnicodeOpKind::Equal => "Equal",
ClassUnicodeOpKind::Colon => "Colon",
ClassUnicodeOpKind::NotEqual => "NotEqual",
})
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for ClassUnicodeOpKind { }Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
ClassUnicodeOpKind {
}
#[automatically_derived]impl ::core::cmp::PartialEq for ClassUnicodeOpKind {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other)
}
}PartialEq)]
1088#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1089pub enum ClassUnicodeOpKind {
1090/// A property set to a specific value, e.g., `\p{scx=Katakana}`.
1091Equal,
1092/// A property set to a specific value using a colon, e.g.,
1093 /// `\p{scx:Katakana}`.
1094Colon,
1095/// A property that isn't a particular value, e.g., `\p{scx!=Katakana}`.
1096NotEqual,
1097}
10981099impl ClassUnicodeOpKind {
1100/// Whether the op is an equality op or not.
1101pub fn is_equal(&self) -> bool {
1102match *self {
1103 ClassUnicodeOpKind::Equal | ClassUnicodeOpKind::Colon => true,
1104_ => false,
1105 }
1106 }
1107}
11081109/// A bracketed character class, e.g., `[a-z0-9]`.
1110#[derive(#[automatically_derived]impl ::core::clone::Clone for ClassBracketed {
#[inline]
fn clone(&self) -> Self {
ClassBracketed {
span: ::core::clone::Clone::clone(&self.span),
negated: ::core::clone::Clone::clone(&self.negated),
kind: ::core::clone::Clone::clone(&self.kind),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for ClassBracketed {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f,
"ClassBracketed span negated kind", &self.span, &self.negated,
&&self.kind)
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for ClassBracketed {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Span>;
let _: ::core::cmp::AssertParamIsEq<bool>;
let _: ::core::cmp::AssertParamIsEq<ClassSet>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
ClassBracketed {
}
#[automatically_derived]impl ::core::cmp::PartialEq for ClassBracketed {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.negated == other.negated && self.span == other.span &&
self.kind == other.kind
}
}PartialEq)]
1111#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1112pub struct ClassBracketed {
1113/// The span of this class.
1114pub span: Span,
1115/// Whether this class is negated or not. e.g., `[a]` is not negated but
1116 /// `[^a]` is.
1117pub negated: bool,
1118/// The type of this set. A set is either a normal union of things, e.g.,
1119 /// `[abc]` or a result of applying set operations, e.g., `[\pL--c]`.
1120pub kind: ClassSet,
1121}
11221123/// A character class set.
1124///
1125/// This type corresponds to the internal structure of a bracketed character
1126/// class. That is, every bracketed character is one of two types: a union of
1127/// items (literals, ranges, other bracketed classes) or a tree of binary set
1128/// operations.
1129#[derive(#[automatically_derived]impl ::core::clone::Clone for ClassSet {
#[inline]
fn clone(&self) -> Self {
match self {
Self::Item(__self_0) =>
ClassSet::Item(::core::clone::Clone::clone(__self_0)),
Self::BinaryOp(__self_0) =>
ClassSet::BinaryOp(::core::clone::Clone::clone(__self_0)),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for ClassSet {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Self::Item(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f, "Item",
&__self_0),
Self::BinaryOp(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"BinaryOp", &__self_0),
}
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for ClassSet {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<ClassSetItem>;
let _: ::core::cmp::AssertParamIsEq<ClassSetBinaryOp>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for ClassSet
{
}
#[automatically_derived]impl ::core::cmp::PartialEq for ClassSet {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other) &&
match (self, other) {
(Self::Item(__self_0), Self::Item(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::BinaryOp(__self_0), Self::BinaryOp(__arg1_0)) =>
__self_0 == __arg1_0,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq)]
1130#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1131pub enum ClassSet {
1132/// An item, which can be a single literal, range, nested character class
1133 /// or a union of items.
1134Item(ClassSetItem),
1135/// A single binary operation (i.e., &&, -- or ~~).
1136BinaryOp(ClassSetBinaryOp),
1137}
11381139impl ClassSet {
1140/// Build a set from a union.
1141pub fn union(ast: ClassSetUnion) -> ClassSet {
1142 ClassSet::Item(ClassSetItem::Union(ast))
1143 }
11441145/// Return the span of this character class set.
1146pub fn span(&self) -> &Span {
1147match *self {
1148 ClassSet::Item(ref x) => x.span(),
1149 ClassSet::BinaryOp(ref x) => &x.span,
1150 }
1151 }
11521153/// Return true if and only if this class set is empty.
1154fn is_empty(&self) -> bool {
1155match *self {
1156 ClassSet::Item(ClassSetItem::Empty(_)) => true,
1157_ => false,
1158 }
1159 }
1160}
11611162/// A single component of a character class set.
1163#[derive(#[automatically_derived]impl ::core::clone::Clone for ClassSetItem {
#[inline]
fn clone(&self) -> Self {
match self {
Self::Empty(__self_0) =>
ClassSetItem::Empty(::core::clone::Clone::clone(__self_0)),
Self::Literal(__self_0) =>
ClassSetItem::Literal(::core::clone::Clone::clone(__self_0)),
Self::Range(__self_0) =>
ClassSetItem::Range(::core::clone::Clone::clone(__self_0)),
Self::Ascii(__self_0) =>
ClassSetItem::Ascii(::core::clone::Clone::clone(__self_0)),
Self::Unicode(__self_0) =>
ClassSetItem::Unicode(::core::clone::Clone::clone(__self_0)),
Self::Perl(__self_0) =>
ClassSetItem::Perl(::core::clone::Clone::clone(__self_0)),
Self::Bracketed(__self_0) =>
ClassSetItem::Bracketed(::core::clone::Clone::clone(__self_0)),
Self::Union(__self_0) =>
ClassSetItem::Union(::core::clone::Clone::clone(__self_0)),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for ClassSetItem {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Self::Empty(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f, "Empty",
&__self_0),
Self::Literal(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"Literal", &__self_0),
Self::Range(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f, "Range",
&__self_0),
Self::Ascii(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f, "Ascii",
&__self_0),
Self::Unicode(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"Unicode", &__self_0),
Self::Perl(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f, "Perl",
&__self_0),
Self::Bracketed(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"Bracketed", &__self_0),
Self::Union(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f, "Union",
&__self_0),
}
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for ClassSetItem {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Span>;
let _: ::core::cmp::AssertParamIsEq<Literal>;
let _: ::core::cmp::AssertParamIsEq<ClassSetRange>;
let _: ::core::cmp::AssertParamIsEq<ClassAscii>;
let _: ::core::cmp::AssertParamIsEq<ClassUnicode>;
let _: ::core::cmp::AssertParamIsEq<ClassPerl>;
let _: ::core::cmp::AssertParamIsEq<Box<ClassBracketed>>;
let _: ::core::cmp::AssertParamIsEq<ClassSetUnion>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
ClassSetItem {
}
#[automatically_derived]impl ::core::cmp::PartialEq for ClassSetItem {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other) &&
match (self, other) {
(Self::Empty(__self_0), Self::Empty(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::Literal(__self_0), Self::Literal(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::Range(__self_0), Self::Range(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::Ascii(__self_0), Self::Ascii(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::Unicode(__self_0), Self::Unicode(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::Perl(__self_0), Self::Perl(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::Bracketed(__self_0), Self::Bracketed(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::Union(__self_0), Self::Union(__arg1_0)) =>
__self_0 == __arg1_0,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq)]
1164#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1165pub enum ClassSetItem {
1166/// An empty item.
1167 ///
1168 /// Note that a bracketed character class cannot contain a single empty
1169 /// item. Empty items can appear when using one of the binary operators.
1170 /// For example, `[&&]` is the intersection of two empty classes.
1171Empty(Span),
1172/// A single literal.
1173Literal(Literal),
1174/// A range between two literals.
1175Range(ClassSetRange),
1176/// An ASCII character class, e.g., `[:alnum:]` or `[:punct:]`.
1177Ascii(ClassAscii),
1178/// A Unicode character class, e.g., `\pL` or `\p{Greek}`.
1179Unicode(ClassUnicode),
1180/// A perl character class, e.g., `\d` or `\W`.
1181Perl(ClassPerl),
1182/// A bracketed character class set, which may contain zero or more
1183 /// character ranges and/or zero or more nested classes. e.g.,
1184 /// `[a-zA-Z\pL]`.
1185Bracketed(Box<ClassBracketed>),
1186/// A union of items.
1187Union(ClassSetUnion),
1188}
11891190impl ClassSetItem {
1191/// Return the span of this character class set item.
1192pub fn span(&self) -> &Span {
1193match *self {
1194 ClassSetItem::Empty(ref span) => span,
1195 ClassSetItem::Literal(ref x) => &x.span,
1196 ClassSetItem::Range(ref x) => &x.span,
1197 ClassSetItem::Ascii(ref x) => &x.span,
1198 ClassSetItem::Perl(ref x) => &x.span,
1199 ClassSetItem::Unicode(ref x) => &x.span,
1200 ClassSetItem::Bracketed(ref x) => &x.span,
1201 ClassSetItem::Union(ref x) => &x.span,
1202 }
1203 }
1204}
12051206/// A single character class range in a set.
1207#[derive(#[automatically_derived]impl ::core::clone::Clone for ClassSetRange {
#[inline]
fn clone(&self) -> Self {
ClassSetRange {
span: ::core::clone::Clone::clone(&self.span),
start: ::core::clone::Clone::clone(&self.start),
end: ::core::clone::Clone::clone(&self.end),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for ClassSetRange {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f,
"ClassSetRange span start end", &self.span, &self.start,
&&self.end)
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for ClassSetRange {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Span>;
let _: ::core::cmp::AssertParamIsEq<Literal>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
ClassSetRange {
}
#[automatically_derived]impl ::core::cmp::PartialEq for ClassSetRange {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.span == other.span && self.start == other.start &&
self.end == other.end
}
}PartialEq)]
1208#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1209pub struct ClassSetRange {
1210/// The span of this range.
1211pub span: Span,
1212/// The start of this range.
1213pub start: Literal,
1214/// The end of this range.
1215pub end: Literal,
1216}
12171218impl ClassSetRange {
1219/// Returns true if and only if this character class range is valid.
1220 ///
1221 /// The only case where a range is invalid is if its start is greater than
1222 /// its end.
1223pub fn is_valid(&self) -> bool {
1224self.start.c <= self.end.c
1225 }
1226}
12271228/// A union of items inside a character class set.
1229#[derive(#[automatically_derived]impl ::core::clone::Clone for ClassSetUnion {
#[inline]
fn clone(&self) -> Self {
ClassSetUnion {
span: ::core::clone::Clone::clone(&self.span),
items: ::core::clone::Clone::clone(&self.items),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for ClassSetUnion {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"ClassSetUnion span items", &self.span, &&self.items)
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for ClassSetUnion {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Span>;
let _: ::core::cmp::AssertParamIsEq<Vec<ClassSetItem>>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
ClassSetUnion {
}
#[automatically_derived]impl ::core::cmp::PartialEq for ClassSetUnion {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.span == other.span && self.items == other.items
}
}PartialEq)]
1230#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1231pub struct ClassSetUnion {
1232/// The span of the items in this operation. e.g., the `a-z0-9` in
1233 /// `[^a-z0-9]`
1234pub span: Span,
1235/// The sequence of items that make up this union.
1236pub items: Vec<ClassSetItem>,
1237}
12381239impl ClassSetUnion {
1240/// Push a new item in this union.
1241 ///
1242 /// The ending position of this union's span is updated to the ending
1243 /// position of the span of the item given. If the union is empty, then
1244 /// the starting position of this union is set to the starting position
1245 /// of this item.
1246 ///
1247 /// In other words, if you only use this method to add items to a union
1248 /// and you set the spans on each item correctly, then you should never
1249 /// need to adjust the span of the union directly.
1250pub fn push(&mut self, item: ClassSetItem) {
1251if self.items.is_empty() {
1252self.span.start = item.span().start;
1253 }
1254self.span.end = item.span().end;
1255self.items.push(item);
1256 }
12571258/// Return this union as a character class set item.
1259 ///
1260 /// If this union contains zero items, then an empty union is
1261 /// returned. If this concatenation contains exactly 1 item, then the
1262 /// corresponding item is returned. Otherwise, ClassSetItem::Union is
1263 /// returned.
1264pub fn into_item(mut self) -> ClassSetItem {
1265match self.items.len() {
12660 => ClassSetItem::Empty(self.span),
12671 => self.items.pop().unwrap(),
1268_ => ClassSetItem::Union(self),
1269 }
1270 }
1271}
12721273/// A Unicode character class set operation.
1274#[derive(#[automatically_derived]impl ::core::clone::Clone for ClassSetBinaryOp {
#[inline]
fn clone(&self) -> Self {
ClassSetBinaryOp {
span: ::core::clone::Clone::clone(&self.span),
kind: ::core::clone::Clone::clone(&self.kind),
lhs: ::core::clone::Clone::clone(&self.lhs),
rhs: ::core::clone::Clone::clone(&self.rhs),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for ClassSetBinaryOp {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field4_finish(f,
"ClassSetBinaryOp span kind lhs rhs", &self.span, &self.kind,
&self.lhs, &&self.rhs)
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for ClassSetBinaryOp {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Span>;
let _: ::core::cmp::AssertParamIsEq<ClassSetBinaryOpKind>;
let _: ::core::cmp::AssertParamIsEq<Box<ClassSet>>;
let _: ::core::cmp::AssertParamIsEq<Box<ClassSet>>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
ClassSetBinaryOp {
}
#[automatically_derived]impl ::core::cmp::PartialEq for ClassSetBinaryOp {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.span == other.span && self.kind == other.kind &&
self.lhs == other.lhs && self.rhs == other.rhs
}
}PartialEq)]
1275#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1276pub struct ClassSetBinaryOp {
1277/// The span of this operation. e.g., the `a-z--[h-p]` in `[a-z--h-p]`.
1278pub span: Span,
1279/// The type of this set operation.
1280pub kind: ClassSetBinaryOpKind,
1281/// The left hand side of the operation.
1282pub lhs: Box<ClassSet>,
1283/// The right hand side of the operation.
1284pub rhs: Box<ClassSet>,
1285}
12861287/// The type of a Unicode character class set operation.
1288///
1289/// Note that this doesn't explicitly represent union since there is no
1290/// explicit union operator. Concatenation inside a character class corresponds
1291/// to the union operation.
1292#[derive(#[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for ClassSetBinaryOpKind {
}
#[automatically_derived]impl ::core::clone::Clone for ClassSetBinaryOpKind {
#[inline]
fn clone(&self) -> Self { *self }
}Clone, #[automatically_derived]impl ::core::marker::Copy for ClassSetBinaryOpKind { }Copy, #[automatically_derived]impl ::core::fmt::Debug for ClassSetBinaryOpKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
ClassSetBinaryOpKind::Intersection => "Intersection",
ClassSetBinaryOpKind::Difference => "Difference",
ClassSetBinaryOpKind::SymmetricDifference =>
"SymmetricDifference",
})
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for ClassSetBinaryOpKind { }Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
ClassSetBinaryOpKind {
}
#[automatically_derived]impl ::core::cmp::PartialEq for ClassSetBinaryOpKind {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other)
}
}PartialEq)]
1293#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1294pub enum ClassSetBinaryOpKind {
1295/// The intersection of two sets, e.g., `\pN&&[a-z]`.
1296Intersection,
1297/// The difference of two sets, e.g., `\pN--[0-9]`.
1298Difference,
1299/// The symmetric difference of two sets. The symmetric difference is the
1300 /// set of elements belonging to one but not both sets.
1301 /// e.g., `[\pL~~[:ascii:]]`.
1302SymmetricDifference,
1303}
13041305/// A single zero-width assertion.
1306#[derive(#[automatically_derived]impl ::core::clone::Clone for Assertion {
#[inline]
fn clone(&self) -> Self {
Assertion {
span: ::core::clone::Clone::clone(&self.span),
kind: ::core::clone::Clone::clone(&self.kind),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for Assertion {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"Assertion span kind", &self.span, &&self.kind)
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for Assertion {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Span>;
let _: ::core::cmp::AssertParamIsEq<AssertionKind>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for Assertion
{
}
#[automatically_derived]impl ::core::cmp::PartialEq for Assertion {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.span == other.span && self.kind == other.kind
}
}PartialEq)]
1307#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1308pub struct Assertion {
1309/// The span of this assertion.
1310pub span: Span,
1311/// The assertion kind, e.g., `\b` or `^`.
1312pub kind: AssertionKind,
1313}
13141315/// An assertion kind.
1316#[derive(#[automatically_derived]impl ::core::clone::Clone for AssertionKind {
#[inline]
fn clone(&self) -> Self {
match self {
Self::StartLine => AssertionKind::StartLine,
Self::EndLine => AssertionKind::EndLine,
Self::StartText => AssertionKind::StartText,
Self::EndText => AssertionKind::EndText,
Self::WordBoundary => AssertionKind::WordBoundary,
Self::NotWordBoundary => AssertionKind::NotWordBoundary,
Self::WordBoundaryStart => AssertionKind::WordBoundaryStart,
Self::WordBoundaryEnd => AssertionKind::WordBoundaryEnd,
Self::WordBoundaryStartAngle =>
AssertionKind::WordBoundaryStartAngle,
Self::WordBoundaryEndAngle => AssertionKind::WordBoundaryEndAngle,
Self::WordBoundaryStartHalf =>
AssertionKind::WordBoundaryStartHalf,
Self::WordBoundaryEndHalf => AssertionKind::WordBoundaryEndHalf,
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for AssertionKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_c_like_enum_write_str(f,
"StartLine EndLine StartText EndText WordBoundary NotWordBoundary WordBoundaryStart WordBoundaryEnd WordBoundaryStartAngle WordBoundaryEndAngle WordBoundaryStartHalf WordBoundaryEndHalf",
match self {
AssertionKind::StartLine => 0usize,
AssertionKind::EndLine => 10usize,
AssertionKind::StartText => 18usize,
AssertionKind::EndText => 28usize,
AssertionKind::WordBoundary => 36usize,
AssertionKind::NotWordBoundary => 49usize,
AssertionKind::WordBoundaryStart => 65usize,
AssertionKind::WordBoundaryEnd => 83usize,
AssertionKind::WordBoundaryStartAngle => 99usize,
AssertionKind::WordBoundaryEndAngle => 122usize,
AssertionKind::WordBoundaryStartHalf => 143usize,
AssertionKind::WordBoundaryEndHalf => 165usize,
})
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for AssertionKind { }Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
AssertionKind {
}
#[automatically_derived]impl ::core::cmp::PartialEq for AssertionKind {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other)
}
}PartialEq)]
1317#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1318pub enum AssertionKind {
1319/// `^`
1320StartLine,
1321/// `$`
1322EndLine,
1323/// `\A`
1324StartText,
1325/// `\z`
1326EndText,
1327/// `\b`
1328WordBoundary,
1329/// `\B`
1330NotWordBoundary,
1331/// `\b{start}`
1332WordBoundaryStart,
1333/// `\b{end}`
1334WordBoundaryEnd,
1335/// `\<` (alias for `\b{start}`)
1336WordBoundaryStartAngle,
1337/// `\>` (alias for `\b{end}`)
1338WordBoundaryEndAngle,
1339/// `\b{start-half}`
1340WordBoundaryStartHalf,
1341/// `\b{end-half}`
1342WordBoundaryEndHalf,
1343}
13441345/// A repetition operation applied to a regular expression.
1346#[derive(#[automatically_derived]impl ::core::clone::Clone for Repetition {
#[inline]
fn clone(&self) -> Self {
Repetition {
span: ::core::clone::Clone::clone(&self.span),
op: ::core::clone::Clone::clone(&self.op),
greedy: ::core::clone::Clone::clone(&self.greedy),
ast: ::core::clone::Clone::clone(&self.ast),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for Repetition {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field4_finish(f,
"Repetition span op greedy ast", &self.span, &self.op,
&self.greedy, &&self.ast)
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for Repetition {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Span>;
let _: ::core::cmp::AssertParamIsEq<RepetitionOp>;
let _: ::core::cmp::AssertParamIsEq<bool>;
let _: ::core::cmp::AssertParamIsEq<Box<Ast>>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
Repetition {
}
#[automatically_derived]impl ::core::cmp::PartialEq for Repetition {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.greedy == other.greedy && self.span == other.span &&
self.op == other.op && self.ast == other.ast
}
}PartialEq)]
1347#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1348pub struct Repetition {
1349/// The span of this operation.
1350pub span: Span,
1351/// The actual operation.
1352pub op: RepetitionOp,
1353/// Whether this operation was applied greedily or not.
1354pub greedy: bool,
1355/// The regular expression under repetition.
1356pub ast: Box<Ast>,
1357}
13581359/// The repetition operator itself.
1360#[derive(#[automatically_derived]impl ::core::clone::Clone for RepetitionOp {
#[inline]
fn clone(&self) -> Self {
RepetitionOp {
span: ::core::clone::Clone::clone(&self.span),
kind: ::core::clone::Clone::clone(&self.kind),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for RepetitionOp {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"RepetitionOp span kind", &self.span, &&self.kind)
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for RepetitionOp {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Span>;
let _: ::core::cmp::AssertParamIsEq<RepetitionKind>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
RepetitionOp {
}
#[automatically_derived]impl ::core::cmp::PartialEq for RepetitionOp {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.span == other.span && self.kind == other.kind
}
}PartialEq)]
1361#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1362pub struct RepetitionOp {
1363/// The span of this operator. This includes things like `+`, `*?` and
1364 /// `{m,n}`.
1365pub span: Span,
1366/// The type of operation.
1367pub kind: RepetitionKind,
1368}
13691370/// The kind of a repetition operator.
1371#[derive(#[automatically_derived]impl ::core::clone::Clone for RepetitionKind {
#[inline]
fn clone(&self) -> Self {
match self {
Self::ZeroOrOne => RepetitionKind::ZeroOrOne,
Self::ZeroOrMore => RepetitionKind::ZeroOrMore,
Self::OneOrMore => RepetitionKind::OneOrMore,
Self::Range(__self_0) =>
RepetitionKind::Range(::core::clone::Clone::clone(__self_0)),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for RepetitionKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Self::ZeroOrOne =>
::core::fmt::Formatter::write_str(f, "ZeroOrOne"),
Self::ZeroOrMore =>
::core::fmt::Formatter::write_str(f, "ZeroOrMore"),
Self::OneOrMore =>
::core::fmt::Formatter::write_str(f, "OneOrMore"),
Self::Range(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f, "Range",
&__self_0),
}
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for RepetitionKind {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<RepetitionRange>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
RepetitionKind {
}
#[automatically_derived]impl ::core::cmp::PartialEq for RepetitionKind {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other) &&
match (self, other) {
(Self::Range(__self_0), Self::Range(__arg1_0)) =>
__self_0 == __arg1_0,
_ => true,
}
}
}PartialEq)]
1372#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1373pub enum RepetitionKind {
1374/// `?`
1375ZeroOrOne,
1376/// `*`
1377ZeroOrMore,
1378/// `+`
1379OneOrMore,
1380/// `{m,n}`
1381Range(RepetitionRange),
1382}
13831384/// A range repetition operator.
1385#[derive(#[automatically_derived]impl ::core::clone::Clone for RepetitionRange {
#[inline]
fn clone(&self) -> Self {
match self {
Self::Exactly(__self_0) =>
RepetitionRange::Exactly(::core::clone::Clone::clone(__self_0)),
Self::AtLeast(__self_0) =>
RepetitionRange::AtLeast(::core::clone::Clone::clone(__self_0)),
Self::Bounded(__self_0, __self_1) =>
RepetitionRange::Bounded(::core::clone::Clone::clone(__self_0),
::core::clone::Clone::clone(__self_1)),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for RepetitionRange {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Self::Exactly(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"Exactly", &__self_0),
Self::AtLeast(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"AtLeast", &__self_0),
Self::Bounded(__self_0, __self_1) =>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"Bounded", __self_0, &__self_1),
}
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for RepetitionRange {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<u32>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
RepetitionRange {
}
#[automatically_derived]impl ::core::cmp::PartialEq for RepetitionRange {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other) &&
match (self, other) {
(Self::Exactly(__self_0), Self::Exactly(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::AtLeast(__self_0), Self::AtLeast(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::Bounded(__self_0, __self_1),
Self::Bounded(__arg1_0, __arg1_1)) =>
__self_0 == __arg1_0 && __self_1 == __arg1_1,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq)]
1386#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1387pub enum RepetitionRange {
1388/// `{m}`
1389Exactly(u32),
1390/// `{m,}`
1391AtLeast(u32),
1392/// `{m,n}`
1393Bounded(u32, u32),
1394}
13951396impl RepetitionRange {
1397/// Returns true if and only if this repetition range is valid.
1398 ///
1399 /// The only case where a repetition range is invalid is if it is bounded
1400 /// and its start is greater than its end.
1401pub fn is_valid(&self) -> bool {
1402match *self {
1403 RepetitionRange::Bounded(s, e) if s > e => false,
1404_ => true,
1405 }
1406 }
1407}
14081409/// A grouped regular expression.
1410///
1411/// This includes both capturing and non-capturing groups. This does **not**
1412/// include flag-only groups like `(?is)`, but does contain any group that
1413/// contains a sub-expression, e.g., `(a)`, `(?P<name>a)`, `(?:a)` and
1414/// `(?is:a)`.
1415#[derive(#[automatically_derived]impl ::core::clone::Clone for Group {
#[inline]
fn clone(&self) -> Self {
Group {
span: ::core::clone::Clone::clone(&self.span),
kind: ::core::clone::Clone::clone(&self.kind),
ast: ::core::clone::Clone::clone(&self.ast),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for Group {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f,
"Group span kind ast", &self.span, &self.kind, &&self.ast)
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for Group {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Span>;
let _: ::core::cmp::AssertParamIsEq<GroupKind>;
let _: ::core::cmp::AssertParamIsEq<Box<Ast>>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for Group { }
#[automatically_derived]impl ::core::cmp::PartialEq for Group {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.span == other.span && self.kind == other.kind &&
self.ast == other.ast
}
}PartialEq)]
1416#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1417pub struct Group {
1418/// The span of this group.
1419pub span: Span,
1420/// The kind of this group.
1421pub kind: GroupKind,
1422/// The regular expression in this group.
1423pub ast: Box<Ast>,
1424}
14251426impl Group {
1427/// If this group is non-capturing, then this returns the (possibly empty)
1428 /// set of flags. Otherwise, `None` is returned.
1429pub fn flags(&self) -> Option<&Flags> {
1430match self.kind {
1431 GroupKind::NonCapturing(ref flags) => Some(flags),
1432_ => None,
1433 }
1434 }
14351436/// Returns true if and only if this group is capturing.
1437pub fn is_capturing(&self) -> bool {
1438match self.kind {
1439 GroupKind::CaptureIndex(_) | GroupKind::CaptureName { .. } => true,
1440 GroupKind::NonCapturing(_) => false,
1441 }
1442 }
14431444/// Returns the capture index of this group, if this is a capturing group.
1445 ///
1446 /// This returns a capture index precisely when `is_capturing` is `true`.
1447pub fn capture_index(&self) -> Option<u32> {
1448match self.kind {
1449 GroupKind::CaptureIndex(i) => Some(i),
1450 GroupKind::CaptureName { ref name, .. } => Some(name.index),
1451 GroupKind::NonCapturing(_) => None,
1452 }
1453 }
1454}
14551456/// The kind of a group.
1457#[derive(#[automatically_derived]impl ::core::clone::Clone for GroupKind {
#[inline]
fn clone(&self) -> Self {
match self {
Self::CaptureIndex(__self_0) =>
GroupKind::CaptureIndex(::core::clone::Clone::clone(__self_0)),
Self::CaptureName { starts_with_p: __self_0, name: __self_1 } =>
GroupKind::CaptureName {
starts_with_p: ::core::clone::Clone::clone(__self_0),
name: ::core::clone::Clone::clone(__self_1),
},
Self::NonCapturing(__self_0) =>
GroupKind::NonCapturing(::core::clone::Clone::clone(__self_0)),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for GroupKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Self::CaptureIndex(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"CaptureIndex", &__self_0),
Self::CaptureName { starts_with_p: __self_0, name: __self_1 } =>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"CaptureName starts_with_p name", __self_0, &__self_1),
Self::NonCapturing(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"NonCapturing", &__self_0),
}
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for GroupKind {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<u32>;
let _: ::core::cmp::AssertParamIsEq<bool>;
let _: ::core::cmp::AssertParamIsEq<CaptureName>;
let _: ::core::cmp::AssertParamIsEq<Flags>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for GroupKind
{
}
#[automatically_derived]impl ::core::cmp::PartialEq for GroupKind {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other) &&
match (self, other) {
(Self::CaptureIndex(__self_0), Self::CaptureIndex(__arg1_0))
=> __self_0 == __arg1_0,
(Self::CaptureName { starts_with_p: __self_0, name: __self_1
}, Self::CaptureName {
starts_with_p: __arg1_0, name: __arg1_1 }) =>
__self_0 == __arg1_0 && __self_1 == __arg1_1,
(Self::NonCapturing(__self_0), Self::NonCapturing(__arg1_0))
=> __self_0 == __arg1_0,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq)]
1458#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1459pub enum GroupKind {
1460/// `(a)`
1461CaptureIndex(u32),
1462/// `(?<name>a)` or `(?P<name>a)`
1463CaptureName {
1464/// True if the `?P<` syntax is used and false if the `?<` syntax is used.
1465starts_with_p: bool,
1466/// The capture name.
1467name: CaptureName,
1468 },
1469/// `(?:a)` and `(?i:a)`
1470NonCapturing(Flags),
1471}
14721473/// A capture name.
1474///
1475/// This corresponds to the name itself between the angle brackets in, e.g.,
1476/// `(?P<foo>expr)`.
1477#[derive(#[automatically_derived]impl ::core::clone::Clone for CaptureName {
#[inline]
fn clone(&self) -> Self {
CaptureName {
span: ::core::clone::Clone::clone(&self.span),
name: ::core::clone::Clone::clone(&self.name),
index: ::core::clone::Clone::clone(&self.index),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for CaptureName {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f,
"CaptureName span name index", &self.span, &self.name,
&&self.index)
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for CaptureName {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Span>;
let _: ::core::cmp::AssertParamIsEq<String>;
let _: ::core::cmp::AssertParamIsEq<u32>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
CaptureName {
}
#[automatically_derived]impl ::core::cmp::PartialEq for CaptureName {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.index == other.index && self.span == other.span &&
self.name == other.name
}
}PartialEq)]
1478pub struct CaptureName {
1479/// The span of this capture name.
1480pub span: Span,
1481/// The capture name.
1482pub name: String,
1483/// The capture index.
1484pub index: u32,
1485}
14861487#[cfg(feature = "arbitrary")]
1488impl arbitrary::Arbitrary<'_> for CaptureName {
1489fn arbitrary(
1490 u: &mut arbitrary::Unstructured,
1491 ) -> arbitrary::Result<CaptureName> {
1492let len = u.arbitrary_len::<char>()?;
1493if len == 0 {
1494return Err(arbitrary::Error::NotEnoughData);
1495 }
1496let mut name: String = String::new();
1497for _ in 0..len {
1498let ch: char = u.arbitrary()?;
1499let cp = u32::from(ch);
1500let ascii_letter_offset = u8::try_from(cp % 26).unwrap();
1501let ascii_letter = b'a' + ascii_letter_offset;
1502 name.push(char::from(ascii_letter));
1503 }
1504Ok(CaptureName { span: u.arbitrary()?, name, index: u.arbitrary()? })
1505 }
15061507fn size_hint(depth: usize) -> (usize, Option<usize>) {
1508 arbitrary::size_hint::and_all(&[
1509 Span::size_hint(depth),
1510 usize::size_hint(depth),
1511 u32::size_hint(depth),
1512 ])
1513 }
1514}
15151516/// A group of flags that is not applied to a particular regular expression.
1517#[derive(#[automatically_derived]impl ::core::clone::Clone for SetFlags {
#[inline]
fn clone(&self) -> Self {
SetFlags {
span: ::core::clone::Clone::clone(&self.span),
flags: ::core::clone::Clone::clone(&self.flags),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for SetFlags {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"SetFlags span flags", &self.span, &&self.flags)
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for SetFlags {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Span>;
let _: ::core::cmp::AssertParamIsEq<Flags>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for SetFlags
{
}
#[automatically_derived]impl ::core::cmp::PartialEq for SetFlags {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.span == other.span && self.flags == other.flags
}
}PartialEq)]
1518#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1519pub struct SetFlags {
1520/// The span of these flags, including the grouping parentheses.
1521pub span: Span,
1522/// The actual sequence of flags.
1523pub flags: Flags,
1524}
15251526/// A group of flags.
1527///
1528/// This corresponds only to the sequence of flags themselves, e.g., `is-u`.
1529#[derive(#[automatically_derived]impl ::core::clone::Clone for Flags {
#[inline]
fn clone(&self) -> Self {
Flags {
span: ::core::clone::Clone::clone(&self.span),
items: ::core::clone::Clone::clone(&self.items),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for Flags {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"Flags span items", &self.span, &&self.items)
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for Flags {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Span>;
let _: ::core::cmp::AssertParamIsEq<Vec<FlagsItem>>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for Flags { }
#[automatically_derived]impl ::core::cmp::PartialEq for Flags {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.span == other.span && self.items == other.items
}
}PartialEq)]
1530#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1531pub struct Flags {
1532/// The span of this group of flags.
1533pub span: Span,
1534/// A sequence of flag items. Each item is either a flag or a negation
1535 /// operator.
1536pub items: Vec<FlagsItem>,
1537}
15381539impl Flags {
1540/// Add the given item to this sequence of flags.
1541 ///
1542 /// If the item was added successfully, then `None` is returned. If the
1543 /// given item is a duplicate, then `Some(i)` is returned, where
1544 /// `items[i].kind == item.kind`.
1545pub fn add_item(&mut self, item: FlagsItem) -> Option<usize> {
1546for (i, x) in self.items.iter().enumerate() {
1547if x.kind == item.kind {
1548return Some(i);
1549 }
1550 }
1551self.items.push(item);
1552None1553 }
15541555/// Returns the state of the given flag in this set.
1556 ///
1557 /// If the given flag is in the set but is negated, then `Some(false)` is
1558 /// returned.
1559 ///
1560 /// If the given flag is in the set and is not negated, then `Some(true)`
1561 /// is returned.
1562 ///
1563 /// Otherwise, `None` is returned.
1564pub fn flag_state(&self, flag: Flag) -> Option<bool> {
1565let mut negated = false;
1566for x in &self.items {
1567match x.kind {
1568 FlagsItemKind::Negation => {
1569 negated = true;
1570 }
1571 FlagsItemKind::Flag(ref xflag) if xflag == &flag => {
1572return Some(!negated);
1573 }
1574_ => {}
1575 }
1576 }
1577None1578 }
1579}
15801581/// A single item in a group of flags.
1582#[derive(#[automatically_derived]impl ::core::clone::Clone for FlagsItem {
#[inline]
fn clone(&self) -> Self {
FlagsItem {
span: ::core::clone::Clone::clone(&self.span),
kind: ::core::clone::Clone::clone(&self.kind),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for FlagsItem {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"FlagsItem span kind", &self.span, &&self.kind)
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for FlagsItem {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Span>;
let _: ::core::cmp::AssertParamIsEq<FlagsItemKind>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for FlagsItem
{
}
#[automatically_derived]impl ::core::cmp::PartialEq for FlagsItem {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.span == other.span && self.kind == other.kind
}
}PartialEq)]
1583#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1584pub struct FlagsItem {
1585/// The span of this item.
1586pub span: Span,
1587/// The kind of this item.
1588pub kind: FlagsItemKind,
1589}
15901591/// The kind of an item in a group of flags.
1592#[derive(#[automatically_derived]impl ::core::clone::Clone for FlagsItemKind {
#[inline]
fn clone(&self) -> Self {
match self {
Self::Negation => FlagsItemKind::Negation,
Self::Flag(__self_0) =>
FlagsItemKind::Flag(::core::clone::Clone::clone(__self_0)),
}
}
}Clone, #[automatically_derived]impl ::core::fmt::Debug for FlagsItemKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Self::Negation =>
::core::fmt::Formatter::write_str(f, "Negation"),
Self::Flag(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f, "Flag",
&__self_0),
}
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for FlagsItemKind {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Flag>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
FlagsItemKind {
}
#[automatically_derived]impl ::core::cmp::PartialEq for FlagsItemKind {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other) &&
match (self, other) {
(Self::Flag(__self_0), Self::Flag(__arg1_0)) =>
__self_0 == __arg1_0,
_ => true,
}
}
}PartialEq)]
1593#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1594pub enum FlagsItemKind {
1595/// A negation operator applied to all subsequent flags in the enclosing
1596 /// group.
1597Negation,
1598/// A single flag in a group.
1599Flag(Flag),
1600}
16011602impl FlagsItemKind {
1603/// Returns true if and only if this item is a negation operator.
1604pub fn is_negation(&self) -> bool {
1605match *self {
1606 FlagsItemKind::Negation => true,
1607_ => false,
1608 }
1609 }
1610}
16111612/// A single flag.
1613#[derive(#[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for Flag {
}
#[automatically_derived]impl ::core::clone::Clone for Flag {
#[inline]
fn clone(&self) -> Self { *self }
}Clone, #[automatically_derived]impl ::core::marker::Copy for Flag { }Copy, #[automatically_derived]impl ::core::fmt::Debug for Flag {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_c_like_enum_write_str(f,
"CaseInsensitive MultiLine DotMatchesNewLine SwapGreed Unicode CRLF IgnoreWhitespace",
match self {
Flag::CaseInsensitive => 0usize,
Flag::MultiLine => 16usize,
Flag::DotMatchesNewLine => 26usize,
Flag::SwapGreed => 44usize,
Flag::Unicode => 54usize,
Flag::CRLF => 62usize,
Flag::IgnoreWhitespace => 67usize,
})
}
}Debug, #[automatically_derived]impl ::core::cmp::Eq for Flag { }Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for Flag { }
#[automatically_derived]impl ::core::cmp::PartialEq for Flag {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other)
}
}PartialEq)]
1614#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1615pub enum Flag {
1616/// `i`
1617CaseInsensitive,
1618/// `m`
1619MultiLine,
1620/// `s`
1621DotMatchesNewLine,
1622/// `U`
1623SwapGreed,
1624/// `u`
1625Unicode,
1626/// `R`
1627CRLF,
1628/// `x`
1629IgnoreWhitespace,
1630}
16311632/// A custom `Drop` impl is used for `Ast` such that it uses constant stack
1633/// space but heap space proportional to the depth of the `Ast`.
1634impl Dropfor Ast {
1635fn drop(&mut self) {
1636use core::mem;
16371638match *self {
1639 Ast::Empty(_)
1640 | Ast::Flags(_)
1641 | Ast::Literal(_)
1642 | Ast::Dot(_)
1643 | Ast::Assertion(_)
1644 | Ast::ClassUnicode(_)
1645 | Ast::ClassPerl(_)
1646// Bracketed classes are recursive, they get their own Drop impl.
1647| Ast::ClassBracketed(_) => return,
1648 Ast::Repetition(ref x) if !x.ast.has_subexprs() => return,
1649 Ast::Group(ref x) if !x.ast.has_subexprs() => return,
1650 Ast::Alternation(ref x) if x.asts.is_empty() => return,
1651 Ast::Concat(ref x) if x.asts.is_empty() => return,
1652_ => {}
1653 }
16541655let empty_span = || Span::splat(Position::new(0, 0, 0));
1656let empty_ast = || Ast::empty(empty_span());
1657let mut stack = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[mem::replace(self, empty_ast())]))vec![mem::replace(self, empty_ast())];
1658while let Some(mut ast) = stack.pop() {
1659match ast {
1660 Ast::Empty(_)
1661 | Ast::Flags(_)
1662 | Ast::Literal(_)
1663 | Ast::Dot(_)
1664 | Ast::Assertion(_)
1665 | Ast::ClassUnicode(_)
1666 | Ast::ClassPerl(_)
1667// Bracketed classes are recursive, so they get their own Drop
1668 // impl.
1669| Ast::ClassBracketed(_) => {}
1670 Ast::Repetition(ref mut x) => {
1671 stack.push(mem::replace(&mut x.ast, empty_ast()));
1672 }
1673 Ast::Group(ref mut x) => {
1674 stack.push(mem::replace(&mut x.ast, empty_ast()));
1675 }
1676 Ast::Alternation(ref mut x) => {
1677 stack.extend(x.asts.drain(..));
1678 }
1679 Ast::Concat(ref mut x) => {
1680 stack.extend(x.asts.drain(..));
1681 }
1682 }
1683 }
1684 }
1685}
16861687/// A custom `Drop` impl is used for `ClassSet` such that it uses constant
1688/// stack space but heap space proportional to the depth of the `ClassSet`.
1689impl Dropfor ClassSet {
1690fn drop(&mut self) {
1691use core::mem;
16921693match *self {
1694 ClassSet::Item(ref item) => match *item {
1695 ClassSetItem::Empty(_)
1696 | ClassSetItem::Literal(_)
1697 | ClassSetItem::Range(_)
1698 | ClassSetItem::Ascii(_)
1699 | ClassSetItem::Unicode(_)
1700 | ClassSetItem::Perl(_) => return,
1701 ClassSetItem::Bracketed(ref x) => {
1702if x.kind.is_empty() {
1703return;
1704 }
1705 }
1706 ClassSetItem::Union(ref x) => {
1707if x.items.is_empty() {
1708return;
1709 }
1710 }
1711 },
1712 ClassSet::BinaryOp(ref op) => {
1713if op.lhs.is_empty() && op.rhs.is_empty() {
1714return;
1715 }
1716 }
1717 }
17181719let empty_span = || Span::splat(Position::new(0, 0, 0));
1720let empty_set = || ClassSet::Item(ClassSetItem::Empty(empty_span()));
1721let mut stack = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[mem::replace(self, empty_set())]))vec![mem::replace(self, empty_set())];
1722while let Some(mut set) = stack.pop() {
1723match set {
1724 ClassSet::Item(ref mut item) => match *item {
1725 ClassSetItem::Empty(_)
1726 | ClassSetItem::Literal(_)
1727 | ClassSetItem::Range(_)
1728 | ClassSetItem::Ascii(_)
1729 | ClassSetItem::Unicode(_)
1730 | ClassSetItem::Perl(_) => {}
1731 ClassSetItem::Bracketed(ref mut x) => {
1732 stack.push(mem::replace(&mut x.kind, empty_set()));
1733 }
1734 ClassSetItem::Union(ref mut x) => {
1735 stack.extend(x.items.drain(..).map(ClassSet::Item));
1736 }
1737 },
1738 ClassSet::BinaryOp(ref mut op) => {
1739 stack.push(mem::replace(&mut op.lhs, empty_set()));
1740 stack.push(mem::replace(&mut op.rhs, empty_set()));
1741 }
1742 }
1743 }
1744 }
1745}
17461747#[cfg(test)]
1748mod tests {
1749use super::*;
17501751// We use a thread with an explicit stack size to test that our destructor
1752 // for Ast can handle arbitrarily sized expressions in constant stack
1753 // space. In case we run on a platform without threads (WASM?), we limit
1754 // this test to Windows/Unix.
1755#[test]
1756 #[cfg(any(unix, windows))]
1757fn no_stack_overflow_on_drop() {
1758use std::thread;
17591760let run = || {
1761let span = || Span::splat(Position::new(0, 0, 0));
1762let mut ast = Ast::empty(span());
1763for i in 0..200 {
1764 ast = Ast::group(Group {
1765 span: span(),
1766 kind: GroupKind::CaptureIndex(i),
1767 ast: Box::new(ast),
1768 });
1769 }
1770assert!(!ast.is_empty());
1771 };
17721773// We run our test on a thread with a small stack size so we can
1774 // force the issue more easily.
1775 //
1776 // NOTE(2023-03-21): It turns out that some platforms (like FreeBSD)
1777 // will just barf with very small stack sizes. So we bump this up a bit
1778 // to give more room to breath. When I did this, I confirmed that if
1779 // I remove the custom `Drop` impl for `Ast`, then this test does
1780 // indeed still fail with a stack overflow. (At the time of writing, I
1781 // had to bump it all the way up to 32K before the test would pass even
1782 // without the custom `Drop` impl. So 16K seems like a safe number
1783 // here.)
1784 //
1785 // See: https://github.com/rust-lang/regex/issues/967
1786thread::Builder::new()
1787 .stack_size(16 << 10)
1788 .spawn(run)
1789 .unwrap()
1790 .join()
1791 .unwrap();
1792 }
17931794// This tests that our `Ast` has a reasonable size. This isn't a hard rule
1795 // and it can be increased if given a good enough reason. But this test
1796 // exists because the size of `Ast` was at one point over 200 bytes on a
1797 // 64-bit target. Wow.
1798#[test]
1799fn ast_size() {
1800let max = 2 * core::mem::size_of::<usize>();
1801let size = core::mem::size_of::<Ast>();
1802assert!(
1803 size <= max,
1804"Ast size of {size} bytes is bigger than suggested max {max}",
1805 );
1806 }
1807}