1use loess::{Error, ErrorPriority, Errors, Input, IntoTokens, PopFrom};
13use proc_macro2::{TokenStream, TokenTree};
14use quote::ToTokens;
15use syn::{
16 Expr, Pat, Path, Stmt,
17 parse::{Parse, ParseStream, Parser},
18};
19
20fn error_reporter(errors: &mut Errors) -> impl '_ + FnOnce(syn::Error) {
21 move |error| {
22 errors.push(Error::new(
23 ErrorPriority::GRAMMAR,
24 error.to_string(),
25 [error.span()],
26 ))
27 }
28}
29
30macro_rules! wrappers {
31 ($(
32 $(#[$($attr:tt)*])*
33 $name:ident($wrapped:ty)$(: $(
34 $(PopFrom $(@ $PopFrom:tt)?)?
36 $(IntoTokens $(@ $IntoTokens:tt)?)?
37 ),*$(,)?)?;
38 )*) => {$(
39 $(#[$($attr)*])*
40 #[derive(Clone)]
41 pub struct $name($wrapped);
42
43 $($(
44 $(
61 $(@ $PopFrom)?
62 impl PopFrom for $name {
63 fn pop_from(input: &mut Input, errors: &mut Errors) -> Result<Self, ()> {
64 fn parse(input: ParseStream) -> syn::Result<($wrapped, TokenStream)> {
65 Ok((<$wrapped>::parse(input)?, TokenStream::parse(input)?))
66 }
67
68 let tokens: TokenStream = input.tokens.drain(..).collect();
69 let (parsed, rest) = parse.parse2(tokens).map_err(error_reporter(errors))?;
70 input.prepend(rest.into_iter().collect::<Vec<_>>());
71 Ok(Self(parsed))
72 }
73 }
74 )?
75
76 $(
77 $(@ $IntoTokens)?
78 impl IntoTokens for $name {
79 fn into_tokens(self, root: &TokenStream, tokens: &mut impl Extend<TokenTree>) {
80 self.0.into_token_stream().into_tokens(root, tokens);
81 }
82 }
83 )?
84 )*)?
85 )*};
86}
87
88wrappers! {
89 Expression(Expr): PopFrom, IntoTokens;
91
92 ExpressionExceptStructExpression(Expr): IntoTokens;
95
96 Pattern(Pat): IntoTokens;
98
99 SimplePath(Path): IntoTokens;
101
102 Statement(Stmt): PopFrom, IntoTokens;
104}
105
106impl PopFrom for ExpressionExceptStructExpression {
107 fn pop_from(input: &mut Input, errors: &mut Errors) -> Result<Self, ()> {
108 fn parse(
109 input: ParseStream,
110 ) -> syn::Result<(ExpressionExceptStructExpression, TokenStream)> {
111 Ok((
112 ExpressionExceptStructExpression(Expr::parse_without_eager_brace(input)?),
113 TokenStream::parse(input)?,
114 ))
115 }
116
117 let tokens = input.tokens.drain(..).collect::<TokenStream>().into();
118 let (this, rest) = parse.parse2(tokens).map_err(error_reporter(errors))?;
119
120 input.prepend(rest.into_iter().collect::<Vec<_>>());
121 Ok(this)
122 }
123}
124
125impl PopFrom for Pattern {
126 fn pop_from(input: &mut Input, errors: &mut Errors) -> Result<Self, ()> {
127 fn parse(input: ParseStream) -> syn::Result<(Pattern, TokenStream)> {
128 Ok((
129 Pattern(Pat::parse_multi_with_leading_vert(input)?),
130 TokenStream::parse(input)?,
131 ))
132 }
133
134 let tokens = input.tokens.drain(..).collect::<TokenStream>().into();
135 let (this, rest) = parse.parse2(tokens).map_err(error_reporter(errors))?;
136
137 input.prepend(rest.into_iter().collect::<Vec<_>>());
138 Ok(this)
139 }
140}
141
142impl PopFrom for SimplePath {
143 fn pop_from(input: &mut Input, errors: &mut Errors) -> Result<Self, ()> {
144 fn parse(input: ParseStream) -> syn::Result<(SimplePath, TokenStream)> {
145 Ok((
146 SimplePath(Path::parse_mod_style(input)?),
147 TokenStream::parse(input)?,
148 ))
149 }
150
151 let tokens = input.tokens.drain(..).collect::<TokenStream>().into();
152 let (this, rest) = parse.parse2(tokens).map_err(error_reporter(errors))?;
153
154 input.prepend(rest.into_iter().collect::<Vec<_>>());
155 Ok(this)
156 }
157}