1#[allow(clippy::wildcard_imports)]
2use super::*;
3
4#[allow(clippy::needless_lifetimes)] impl<'ty, T, S: ?Sized> NamedRule for for<'index, 'cursor> fn(&'cursor mut &'ty S, &'index mut usize) -> Result<T, ParseError> {
6 fn name(&self) -> Option<&'static str> { Some("<anonymous rule>") }
7}
8impl<'ty, T, S: ?Sized> Rule<'ty, S> for for<'index, 'cursor> fn(&'cursor mut &'ty S, &'index mut usize) -> Result<T, ParseError> {
9 type Output = T;
10
11 fn parse_at<'cursor, 'this, 'index>(&'this self, input: &'cursor mut &'ty S, index: &'index mut usize) -> Result<T, ParseError> where 'ty: 'this {
12 let before = (*input, *index);
13 self(input, index).map_err(|err| {
14 (*input, *index) = before;
15 ParseError::new(Some(Box::new(err)), self.name(), *index)
16 })
17 }
18}
19impl<T> NamedRule for for<'a> fn(&'a T) -> bool {
20 fn name(&self) -> Option<&'static str> { Some("<anonymous pattern>") }
21}
22
23impl<'input, T: 'input> Rule<'input, [T]> for for<'a> fn(&'a T) -> bool {
24 type Output = &'input T;
25
26 fn parse_at<'cursor, 'this, 'index>(&'this self, input: &'cursor mut &'input [T], index: &'index mut usize) -> Result<Self::Output, ParseError> where 'input: 'this {
27 if let Some(first) = input.first().and_then(|v| self(v).then_some(v)) {
28 *input = &input[1..];
29 *index += 1;
30 return Ok(first);
31 }
32 Err(ParseError::new(Some(Box::new(UnmatchedInput)), self.name(), *index))
33 }
34}
35
36impl<'input> Rule<'input, str> for fn(&char) -> bool {
37 type Output = char;
38
39 fn parse_at<'cursor, 'this, 'index>(&'this self, input: &'cursor mut &'input str, index: &'index mut usize) -> Result<Self::Output, ParseError> where 'input: 'this {
40 if let Some((chr, idx)) = input.chars().next().and_then(|chr| self(&chr).then_some((chr, chr.len_utf8()))) {
41 *input = &input[idx..];
42 *index += idx;
43 return Ok(chr);
44 }
45 Err(ParseError::new(Some(Box::new(UnmatchedInput)), self.name(), *index))
46 }
47}
48
49impl NamedRule for char {
50 fn name(&self) -> Option<&'static str> { Some("<single character>") }
51}
52impl<'input> Rule<'input, str> for char {
53 type Output = char;
54
55 fn parse_at<'cursor, 'this, 'index>(&'this self, input: &'cursor mut &'input str, index: &'index mut usize) -> Result<Self::Output, ParseError> where 'input: 'this {
56 let Some(chr) = input.chars().next() else {
57 return Err(ParseError::new(Some(Box::new(UnexpectedEOF)), self.name(), *index))
58 };
59 if chr != *self {
60 return Err(ParseError::new(Some(Box::new(Unexpected::<char>::new(chr))), self.name(), *index))
61 }
62 let len = chr.len_utf8();
63 *index += len;
64 *input = &input[len..];
65 Ok(*self)
66 }
67}
68
69impl<T> NamedRule for [T] {
70 fn name(&self) -> Option<&'static str> { Some("<slice literal>") }
71}
72impl<'input, T: PartialEq + 'input> Rule<'input, [T]> for [T] {
73 type Output = &'input [T];
74
75 fn parse_at<'cursor, 'this, 'index>(&'this self, input: &'cursor mut &'input [T], index: &'index mut usize) -> Result<Self::Output, ParseError> where 'input: 'this {
76 if let Some(after) = input.strip_prefix(self) {
77 let res = &input[..self.len()];
78 *input = after;
79 *index += self.len();
80 Ok(res)
81 } else { Err(ParseError::new(Some(Box::new(NoMatch)), self.name(), *index)) }
82 }
83}
84
85impl<const N: usize, T> NamedRule for [T; N] {
86 fn name(&self) -> Option<&'static str> { Some("<array literal>") }
87}
88impl<'input, const N: usize, T: PartialEq + 'input> Rule<'input, [T]> for [T; N] {
89 type Output = &'input [T];
90
91 #[inline]
92 fn parse_at<'cursor, 'this, 'index>(&'this self, input: &'cursor mut &'input [T], index: &'index mut usize) -> Result<Self::Output, ParseError> where 'input: 'this {
93 self[..].parse_at(input, index)
94 }
95}
96
97impl NamedRule for str {
98 fn name(&self) -> Option<&'static str> { Some("<string literal>") }
99}
100impl<'input> Rule<'input, str> for str {
101 type Output = &'input str;
102
103 fn parse_at<'cursor, 'this, 'index>(&'this self, input: &'cursor mut &'input str, index: &'index mut usize) -> Result<Self::Output, ParseError> where 'input: 'this {
104 if let Some(after) = input.strip_prefix(self) {
105 let res = &input[..self.len()];
106 *input = after;
107 *index += self.len();
108 Ok(res)
109 } else { Err(ParseError::new(Some(Box::new(NoMatch)), self.name(), *index)) }
110 }
111}
112
113impl<T: NamedRule + ?Sized> NamedRule for &T {
114 #[inline] fn name(&self) -> Option<&'static str> { (*self).name() }
115}
116impl<'input, S: ?Sized + 'input, T: ?Sized + Rule<'input, S>> Rule<'input, S> for &T {
117 type Output = <T as Rule<'input, S>>::Output;
118
119 fn parse_at<'cursor, 'this, 'index>(&'this self, input: &'cursor mut &'input S, index: &'index mut usize) -> Result<Self::Output, ParseError> where 'input: 'this {
120 (**self).parse_at(input, index)
121 }
122}