1use syn::{
2 parse::{discouraged::Speculative, Parse, ParseStream},
3 token::Token,
4};
5
6pub trait Validate {
7 fn validate(stream: &ParseStream) -> bool;
8}
9
10impl<T> Validate for T
11where
12 T: Token,
13{
14 fn validate(stream: &ParseStream) -> bool {
15 T::peek(stream.cursor())
16 }
17}
18
19pub trait SpeculativeValidate: Parse {
20 fn speculative_validate(stream: &ParseStream) -> Option<Self> {
21 let fork = stream.fork();
22
23 match Self::parse(&fork) {
24 Ok(parsed) => {
25 stream.advance_to(&fork);
26 Some(parsed)
27 }
28 Err(_) => None,
29 }
30 }
31}
32
33impl<T> SpeculativeValidate for T where T: Parse {}
34
35#[macro_export]
36macro_rules! try_parse {
37 ($input:expr => $ty:ty) => {{
38 use syn::parse::discouraged::Speculative;
39
40 let fork = $input.fork();
41
42 match <$ty>::parse(&fork) {
43 Ok(parsed) => {
44 $input.advance_to(&fork);
45 Some(parsed)
46 }
47 Err(_) => None,
48 }
49 }};
50}