1use std::fmt::{self, Debug};
23use crate::{expr::IndexedCaptures, haystack::{HaystackItem, HaystackOf}};
45pub trait Matcher<I: HaystackItem>: Debug + Default {
6/// Checks if the start of the haystack contains a match for this [`Matcher`]. If this method
7 /// successfully matches the start of the haystack, `hay` is progressed so that `hay.item()`
8 /// hasn't been matched yet. On a fail, the state of hay is undefined.
9fn matches<'a, H: HaystackOf<'a, I>>(hay: &mut H) -> bool;
1011// It would be nice to use a custom Iterator here rather than a Vec, but reversing an arbitrary
12 // match is not easy, so we just progress through linearly and store them all.
13 // This could cause issues with huge haystacks, but: all regexes need to be compiled at compile
14 // time and are hence controlled by the author. If their pattern will be operating on huge
15 // haystacks and need backtracking, that's up to them.
1617/// Produces a Vec of all valid haystack states produced as the result of a valid match at the
18 /// start of `hay`, used to implement backtracking. The Vec is produced in reverse priority
19 /// order, so the last match has the highest priority. After calling all_matches, the state of
20 /// `hay` itself is undefined.
21 ///
22 /// # Required
23 /// This method needs to be implemented by all [`Matcher`]s that can match more than one string
24 /// of characters from a haystack.
25fn all_matches<'a, H: HaystackOf<'a, I>>(hay: &mut H) -> Vec<usize> {
26if Self::matches(hay) {
27<[_]>::into_vec(::alloc::boxed::box_new([hay.index()]))vec![hay.index()]28 } else {
29::alloc::vec::Vec::new()vec![]30 }
31 }
3233/// Checks if the start of the haystack contains a match for this Matcher, writing any groups
34 /// to `caps`. Similar to [`matches`], this method progresses `hay` and `caps` on a success. On
35 /// a fail, they have undefined states.
36 ///
37 /// # Required
38 /// This method needs to be implemented for capturing groups or any type that holds other
39 /// [`Matcher`]s, so that it can redirect to the relevant `capture` methods.
40fn captures<'a, H: HaystackOf<'a, I>>(hay: &mut H, caps: &mut IndexedCaptures) -> bool {
41let _ = caps;
42Self::matches(hay)
43 }
4445/// Produces a Vec of all valid captures (and accompanying haystack states) present at the start
46 /// of `hay`. Used to implement backtracking for capturing methods. As with
47 /// [`all_matches`](Matcher::all_matches), the resulting Vec is produced in reverse priority
48 /// order. After calling all_captures, the state of `hay` and `caps` are undefined.
49 ///
50 /// # Required
51 /// This method needs to be implemented for any type that also implements
52 /// [`captures`](Matcher::captures) and [`all_matches`](Matcher::all_matches).
53fn all_captures<'a, H: HaystackOf<'a, I>>(
54 hay: &mut H,
55 caps: &mut IndexedCaptures
56 ) -> Vec<(usize, IndexedCaptures)> {
57if Self::captures(hay, caps) {
58<[_]>::into_vec(::alloc::boxed::box_new([(hay.index(), caps.clone())]))vec![(hay.index(), caps.clone())]59 } else {
60::alloc::vec::Vec::new()vec![]61 }
62 }
63}
6465#[derive(#[automatically_derived]
impl<const N : u8> ::core::default::Default for Byte<N> {
#[inline]
fn default() -> Byte<N> { Byte {} }
}Default)]
66pub struct Byte<const N: u8>;
6768impl<const N: u8> Matcher<u8> for Byte<N> {
69fn matches<'a, H: HaystackOf<'a, u8>>(hay: &mut H) -> bool {
70if hay.item() == Some(N) {
71 hay.progress();
72true
73} else {
74false
75}
76 }
77}
7879impl<const N: u8> Debug for Byte<N> {
80fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81f.write_fmt(format_args!("{0:#04x}", N))write!(f, "{N:#04x}")82 }
83}
8485#[derive(#[automatically_derived]
impl<const A : u8, const B : u8> ::core::default::Default for ByteRange<A, B>
{
#[inline]
fn default() -> ByteRange<A, B> { ByteRange {} }
}Default)]
86pub struct ByteRange<const A: u8, const B: u8>;
8788impl<const A: u8, const B: u8> Matcher<u8> for ByteRange<A, B> {
89fn matches<'a, H: HaystackOf<'a, u8>>(hay: &mut H) -> bool {
90if let Some(byte) = hay.item() && A <= byte && byte <= B {
91 hay.progress();
92true
93} else {
94false
95}
96 }
97}
9899impl<const A: u8, const B: u8> Debug for ByteRange<A, B> {
100fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
101f.write_fmt(format_args!("[{0:#04x}-{1:#04x}]", A, B))write!(f, "[{A:#04x}-{B:#04x}]")102 }
103}
104105#[derive(#[automatically_derived]
impl<const N : char> ::core::default::Default for Scalar<N> {
#[inline]
fn default() -> Scalar<N> { Scalar {} }
}Default)]
106pub struct Scalar<const N: char>;
107108impl<const N: char> Matcher<char> for Scalar<N> {
109fn matches<'a, H: HaystackOf<'a, char>>(hay: &mut H) -> bool {
110if hay.item() == Some(N) {
111 hay.progress();
112true
113} else {
114false
115}
116 }
117}
118119impl<const N: char> Debug for Scalar<N> {
120fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
121f.write_fmt(format_args!("{0}", N.escape_debug()))write!(f, "{}", N.escape_debug())122 }
123}
124125#[derive(#[automatically_derived]
impl<const A : char, const B : char> ::core::default::Default for
ScalarRange<A, B> {
#[inline]
fn default() -> ScalarRange<A, B> { ScalarRange {} }
}Default)]
126pub struct ScalarRange<const A: char, const B: char>;
127128impl<const A: char, const B: char> Matcher<char> for ScalarRange<A, B> {
129fn matches<'a, H: HaystackOf<'a, char>>(hay: &mut H) -> bool {
130if let Some(scalar) = hay.item() && A <= scalar && scalar <= B {
131 hay.progress();
132true
133} else {
134false
135}
136 }
137}
138139impl<const A: char, const B: char> Debug for ScalarRange<A, B> {
140fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141f.write_fmt(format_args!("[{0}-{1}]", A.escape_debug(), B.escape_debug()))write!(f, "[{}-{}]", A.escape_debug(), B.escape_debug())142 }
143}
144145#[derive(#[automatically_derived]
impl ::core::default::Default for Always {
#[inline]
fn default() -> Always { Always {} }
}Default)]
146pub struct Always;
147148impl<I: HaystackItem> Matcher<I> for Always {
149fn matches<'a, H: HaystackOf<'a, I>>(_hay: &mut H) -> bool {
150true
151}
152}
153154impl Debug for Always {
155fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
156f.write_fmt(format_args!("()"))write!(f, "()")157 }
158}
159160#[derive(#[automatically_derived]
impl ::core::default::Default for Beginning {
#[inline]
fn default() -> Beginning { Beginning {} }
}Default)]
161pub struct Beginning;
162163impl<I: HaystackItem> Matcher<I> for Beginning {
164fn matches<'a, H: HaystackOf<'a, I>>(hay: &mut H) -> bool {
165 hay.is_start()
166 }
167}
168169impl Debug for Beginning {
170fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
171f.write_fmt(format_args!("^"))write!(f, "^")172 }
173}
174175#[derive(#[automatically_derived]
impl ::core::default::Default for End {
#[inline]
fn default() -> End { End {} }
}Default)]
176pub struct End;
177178impl<I: HaystackItem> Matcher<I> for End {
179fn matches<'a, H: HaystackOf<'a, I>>(hay: &mut H) -> bool {
180 hay.is_end()
181 }
182}
183184impl Debug for End {
185fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
186f.write_fmt(format_args!("$"))write!(f, "$")187 }
188}