1use std::borrow::Cow;
2
3use crate::{
4 call_site, Delimiter, MacroStream, MacrosError, Match, Parse, ParseError, ParseErrorKind,
5 ParserOutput, Spacing, Token,
6};
7use proc_macro_error::{abort, abort_call_site};
8
9#[doc(hidden)]
10pub struct ParserInput<T>
11where
12 T: ToOwned<Owned = T> + ParserOutput,
13{
14 pub patterns: Vec<Pattern<T>>,
15}
16
17pub enum Pattern<T>
33where
34 T: ToOwned<Owned = T> + ParserOutput,
35{
36 Optional(Vec<Pattern<T>>),
37 Parameter(Vec<Pattern<T>>, String),
38 ZeroOrMore(Vec<Pattern<T>>, bool),
39 OneOrMore(Vec<Pattern<T>>, bool),
40 Choice(Vec<Vec<Pattern<T>>>),
41 Token(Token),
42 Group(Delimiter, Vec<Pattern<T>>),
43 Any,
44 #[allow(clippy::type_complexity)]
45 Validator(
46 Option<MacroStream>,
47 Option<for<'a> fn(Cow<'a, T>, &Match) -> (Result<(), String>, Cow<'a, T>)>,
48 ),
49}
50
51impl<T> ParserInput<T>
52where
53 T: ToOwned<Owned = T> + ParserOutput,
54{
55 pub fn params(&self) -> Vec<(String, bool)> {
56 let mut params = vec![];
57 for pattern in &self.patterns {
58 params.extend(pattern.params());
59 }
60 params
61 }
62}
63
64impl<T> Parse for ParserInput<T>
65where
66 T: ToOwned<Owned = T> + ParserOutput,
67{
68 fn parse(stream: &mut MacroStream) -> Result<Self, MacrosError> {
69 Ok(Self {
70 patterns: stream_to_patterns(stream)?,
71 })
72 }
73}
74
75fn stream_to_patterns<T>(stream: &mut MacroStream) -> Result<Vec<Pattern<T>>, MacrosError>
76where
77 T: ToOwned<Owned = T> + ParserOutput,
78{
79 let mut patterns = Vec::new();
80 let mut prev = None;
81 while !stream.is_empty() {
82 let current = Pattern::parse(stream)?;
83 if let (Some(&Pattern::Validator(_, _)) | None, Pattern::Validator(_, _)) = (prev, ¤t)
84 {
85 return Err(ParseError::new(
86 stream.peek().map(|t| t.span()).unwrap_or_else(call_site),
87 ParseErrorKind::InvalidValidatorPosition,
88 )
89 .into());
90 }
91 patterns.push(current);
92 prev = Some(patterns.last().unwrap());
93 }
94 Ok(patterns)
95}
96
97impl<T> Parse for Pattern<T>
98where
99 T: ToOwned<Owned = T> + ParserOutput,
100{
101 fn parse(input: &mut MacroStream) -> Result<Self, MacrosError> {
102 let token = input.pop_or_err().map_err(|mut e| {
103 e.unexpected_end_of_input("started parsing a pattern and found no start");
104 e
105 })?;
106 Ok(match token {
107 Token::Group {
108 delimiter: Delimiter::Brace,
109 mut stream,
110 ..
111 } => {
112 let token = stream.pop_or_err();
113 let ending = input.peek();
114 match token {
115 Ok(Token::Group {
116 delimiter: Delimiter::Brace,
117 stream: mut inner_stream,
118 ..
119 }) if stream.is_empty() => {
120 Self::Group(Delimiter::Brace, stream_to_patterns(&mut inner_stream)?)
121 },
122 Ok(token) => {
123 let t = match ending {
124 Some(Token::Punctuation { value: '?', spacing: Spacing::Alone, .. }) => {
125 stream.push_front(token);
126 Self::Optional(stream_to_patterns(&mut stream)?)
127 },
128 Some(Token::Punctuation { value: '*', spacing: Spacing::Alone, .. }) => {
129 stream.push_front(token);
130 Self::ZeroOrMore(stream_to_patterns(&mut stream)?, false)
131 },
132 Some(Token::Punctuation { value: '*', spacing: Spacing::Joint, .. }) => {
133 stream.push_front(token);
134 Self::ZeroOrMore(stream_to_patterns(&mut stream)?, match input.peek_at(1) {
135 Some(Token::Punctuation { value: '*', spacing: Spacing::Alone, .. }) => {
136 input.pop(); true
138 },
139 _ => false
140 })
141
142 }
143 Some(Token::Punctuation { value: '+', spacing: Spacing::Alone, .. }) => {
144 stream.push_front(token);
145 Self::OneOrMore(stream_to_patterns(&mut stream)?, false)
146 },
147 Some(Token::Punctuation { value: '+', spacing: Spacing::Joint, .. }) => {
148 stream.push_front(token);
149 Self::OneOrMore(stream_to_patterns(&mut stream)?, match input.peek_at(1) {
150 Some(Token::Punctuation { value: '+', spacing: Spacing::Alone, .. }) => {
151 input.pop(); true
153 },
154 _ => false
155 })
156 }
157 Some(Token::Punctuation { value: '@', spacing: Spacing::Alone, .. }) => {
158 let mut span = token.span();
159 stream.push_front(token);
160 let mut patterns = vec![];
161 while !stream.is_empty() {
162 let token = stream.peek();
163 if let Some(token) = token.as_ref() {
164 span = token.span();
165 }
166 match token {
167 Some(Token::Punctuation { value: ':', spacing: Spacing::Alone, .. }) => {
168 stream.pop();
169 break;
170 },
171 _ => patterns.push(Pattern::parse(&mut stream)?),
172 }
173 }
174 if stream.is_empty() {
175 abort!(span, "expected a pattern, a colon, then an ident, (like some_pattern_here:name), found end of input");
176 }
177 if patterns.is_empty() {
178 abort!(span, "expected a pattern, a colon, then an ident, (like some_pattern_here:name), found no pattern");
179 }
180 let token = stream.pop_or_err()?;
181 match token {
182 Token::Ident { name, .. } => Self::Parameter(patterns, name),
183 _ => abort!(token.span(), "expected an identifier"),
184 }
185 },
186 Some(Token::Punctuation { value: '&', spacing: Spacing::Alone, .. }) => {
187 stream.push_front(token);
188 let mut patterns = vec![];
189 let mut current = vec![];
190 while !stream.is_empty() {
191 let token = stream.peek();
192 match token {
193 Some(Token::Punctuation { value: '|', spacing: Spacing::Alone, .. }) => {
194 if !current.is_empty() {
195 patterns.push(current);
196 current = vec![];
197 }
198 stream.pop();
199 continue;
200 },
201 _ => current.push(Pattern::parse(&mut stream)?),
202 }
203 }
204 if !current.is_empty() {
205 patterns.push(current);
206 }
207 Self::Choice(patterns)
208 },
209 Some(Token::Punctuation { value: '$', spacing: Spacing::Alone, .. }) => {
210 Self::Any
211 },
212 Some(Token::Punctuation { value: '=', spacing: Spacing::Alone, .. }) => {
213 stream.push_front(token);
214 Self::Validator(Some(stream), None)
215 },
216 _ => {
217 abort!(token.span(), "expected one of ?*+=~@&$ after single braces")
218 },
219 };
220 input.pop();
221 t
222 },
223 Err(_) => match ending {
224 Some(Token::Punctuation { value: '$', spacing: Spacing::Alone, .. }) => {
225 input.pop();
226 Self::Any
227 },
228 _ => abort_call_site!("found empty group, expected either an any pattern (like {}$) after the braces or something in the braces"),
229 },
230 }
231 },
232 Token::Punctuation { value: '~', .. } => {
233 let next = input.pop_or_err().map_err(|mut e| {
234 e.unexpected_end_of_input("started parsing a pattern and found no start");
235 e
236 })?;
237 match next {
238 next @ Token::Punctuation {
239 value: '?' | '*' | '+' | '=' | '~' | '@' | '&' | '$',
240 ..
241 } => Self::Token(next),
242 _ => abort!(next.span(), "expected one of ?*+=~@&$ after tilde"),
243 }
244 },
245 Token::Group {
246 delimiter,
247 mut stream,
248 ..
249 } => Self::Group(delimiter, stream_to_patterns(&mut stream)?),
250 token => Self::Token(token),
251 })
252 }
253}
254
255impl<T> Pattern<T>
256where
257 T: ToOwned<Owned = T> + ParserOutput,
258{
259 pub fn params(&self) -> Vec<(String, bool)> {
260 let mut params = vec![];
261 match self {
262 Self::Group(_, patterns) => {
263 for i in patterns {
264 params.extend(i.params());
265 }
266 },
267 Self::Optional(patterns) => {
268 for i in patterns {
269 params.extend(i.params().into_iter().map(|(name, _)| (name, true)));
270 }
271 },
272 Self::ZeroOrMore(patterns, _) => {
273 for i in patterns {
274 params.extend(i.params());
275 }
276 },
277 Self::OneOrMore(patterns, _) => {
278 for i in patterns {
279 params.extend(i.params());
280 }
281 },
282 Self::Choice(patterns) => {
283 for i in patterns {
284 for j in i {
285 params.extend(j.params());
286 }
287 }
288 },
289 Self::Parameter(patterns, name) => {
290 for i in patterns {
291 params.extend(i.params());
292 }
293 params.push((name.clone(), false));
294 },
295 _ => {},
296 };
297 params
298 }
299
300 pub fn match_pattern<'a>(
301 &self,
302 mut output: Cow<'a, T>,
303 next: Option<&Pattern<T>>,
304 next2: Option<&Pattern<T>>,
305 stream: &mut MacroStream,
306 ) -> (Result<Match, MacrosError>, Cow<'a, T>) {
307 let match_next = match next {
308 Some(Pattern::Validator(_, _)) => next2,
309 _ => next,
310 };
311 let res = match self {
312 Self::Any => (
313 stream
314 .pop_or_err()
315 .map(Match::One)
316 .map_err(MacrosError::Parse),
317 output,
318 ),
319 Self::Choice(choices) => {
320 'choice: for choice in choices {
321 let mut fork = stream.fork();
322 let (res, o) = Self::match_patterns(output, choice, &mut fork);
323 if res.is_err() {
324 output = o;
325 continue 'choice;
326 }
327 stream.pop_many(fork.popped());
328 return (res, o);
329 }
330 (
331 Err(MacrosError::Parse(ParseError::new(
332 stream.peek().map(|t| t.span()).unwrap_or_else(call_site),
333 ParseErrorKind::NoMatchingChoice,
334 ))),
335 output,
336 )
337 },
338 Self::Group(delimiter, patterns) => {
339 let token = match stream.pop_or_err().map_err(MacrosError::Parse) {
340 Ok(token) => token,
341 Err(e) => return (Err(e), output),
342 };
343 if let Token::Group {
344 delimiter: d,
345 stream: s,
346 ..
347 } = &token
348 {
349 if d == delimiter {
350 let mut fork = s.fork();
351 let (res, o) = Self::match_patterns(output, patterns, &mut fork);
352 if !fork.is_empty() {
353 return (
354 Err(MacrosError::Parse(ParseError::new(
355 stream.peek().map(|t| t.span()).unwrap_or_else(call_site),
356 ParseErrorKind::InputTooLong,
357 ))),
358 o,
359 );
360 }
361 stream.pop_many(fork.popped());
362 return (res, o);
363 }
364 }
365 (
366 Err(MacrosError::Parse(ParseError::new(
367 token.span(),
368 ParseErrorKind::ExpectedGroup(*delimiter),
369 ))),
370 output,
371 )
372 },
373 Self::OneOrMore(patterns, greedy) => {
374 let mut matches = vec![];
375 loop {
376 let mut fork = stream.fork();
377 match Self::match_patterns(output, patterns, &mut fork) {
378 (Ok(m), o) => {
379 stream.pop_many(fork.popped());
380 matches.push(m);
381 output = o;
382 },
383 (Err(_), o) => {
384 output = o;
385 break;
386 },
387 }
388 match match_next {
389 Some(next) if !greedy && !matches.is_empty() => {
390 match next.match_pattern(output, None, None, &mut fork) {
391 (Ok(_), o) => {
392 output = o;
393 break;
394 },
395 (_, o) => output = o,
396 }
397 },
398 _ => {},
399 }
400 }
401 (
402 if matches.is_empty() {
403 Err(MacrosError::Parse(ParseError::new(
404 stream.peek().map(|t| t.span()).unwrap_or_else(call_site),
405 ParseErrorKind::ExpectedRepetition,
406 )))
407 } else {
408 Ok(Match::Many(matches))
409 },
410 output,
411 )
412 },
413 Self::ZeroOrMore(patterns, greedy) => {
414 let mut matches = vec![];
415 loop {
416 let mut fork = stream.fork();
417 match Self::match_patterns(output, patterns, &mut fork) {
418 (Ok(m), o) => {
419 stream.pop_many(fork.popped());
420 matches.push(m);
421 output = o;
422 },
423 (_, o) => {
424 output = o;
425 break;
426 },
427 }
428 match match_next {
429 Some(next) if !greedy => {
430 match next.match_pattern(output.clone(), None, None, &mut fork) {
431 (Ok(_), o) => {
432 output = o;
433 break;
434 },
435 (_, o) => output = o,
436 }
437 },
438 _ => {},
439 }
440 }
441 (
442 if matches.is_empty() {
443 Ok(Match::None)
444 } else {
445 Ok(Match::Many(matches))
446 },
447 output,
448 )
449 },
450 Self::Optional(patterns) => {
451 let mut fork = stream.fork();
452 match Self::match_patterns(output.clone(), patterns, &mut fork) {
453 r @ (Ok(_), _) => {
454 stream.pop_many(fork.popped());
455 r
456 },
457 (_, o) => (Ok(Match::None), o),
458 }
459 },
460 Self::Token(token) => (
461 match stream.pop_or_err().map_err(MacrosError::Parse) {
462 Ok(t) if t == *token => Ok(Match::One(t)),
463 Ok(t) => Err(MacrosError::Parse(ParseError::new(
464 t.span(),
465 ParseErrorKind::Expected(token.clone(), t),
466 ))),
467 Err(e) => Err(e),
468 },
469 output,
470 ),
471 Self::Parameter(patterns, name) => {
472 let mut fork = stream.fork();
473 let (res, mut o) = Self::match_patterns(output, patterns, &mut fork);
474 match res {
475 Ok(m) => {
476 stream.pop_many(fork.popped());
477 o.to_mut().set_match(name, m.clone());
478 (Ok(m), o)
479 },
480 Err(e) => (Err(e), o),
481 }
482 },
483 Self::Validator(_, _) => panic!(
484 "Validator pattern should not have been passed into `Pattern::match_pattern`"
485 ),
486 };
487 match (next, res) {
488 (Some(Pattern::Validator(_, Some(f))), (Ok(m), output)) => match f(output, &m) {
489 (Ok(_), o) => (Ok(m), o),
490 (Err(e), o) => (
491 Err(MacrosError::Parse(ParseError::new(
492 stream.peek().map(|t| t.span()).unwrap_or_else(call_site),
493 ParseErrorKind::ValidatorFailed(e),
494 ))),
495 o,
496 ),
497 },
498 (_, m) => m,
499 }
500 }
501
502 pub fn match_patterns<'b, 'a: 'b>(
503 mut output: Cow<'a, T>,
504 patterns: &'b [Pattern<T>],
505 stream: &mut MacroStream,
506 ) -> (Result<Match, MacrosError>, Cow<'a, T>) {
507 let mut matches = vec![];
508 let mut fork = stream.fork();
509 for (i, pattern) in patterns.iter().enumerate() {
510 if let Pattern::Validator(_, _) = pattern {
511 continue;
512 }
513 match pattern.match_pattern(output, patterns.get(i + 1), patterns.get(i + 2), &mut fork)
514 {
515 (Ok(m @ Match::One(_)), o) => {
516 matches.push(m);
517 output = o;
518 },
519 (Ok(Match::None), o) => output = o,
520 (Ok(Match::Many(m)), o) => {
521 matches.extend(m);
522 output = o;
523 },
524 e => return e,
525 }
526 }
527 stream.pop_many(fork.popped());
528 (Ok(Match::Many(matches)), output)
529 }
530}
531
532unsafe impl<T> Sync for Pattern<T> where T: ToOwned<Owned = T> + ParserOutput {}