macroscope/
validate.rs

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}