1//! Types for parsing arguments, shared by many of the macros
2
3use crate::{
4 parse_utils::{MyParse, ParseBuffer, ParseStream},
5 spanned::Spans,
6};
7
8use proc_macro2::TokenStream as TokenStream2;
9
10use quote::ToTokens;
11
12////////////////////////////////////////////////
13
14// An expression inside `(...)`
15pub(crate) struct ExprArg {
16 pub(crate) span: Spans,
17 /// Using a TokenStream2 because it is validated to be a valid expression in
18 /// the macro_rules! macros that call these proc macros.
19 pub(crate) expr: TokenStream2,
20}
21
22impl ToTokens for ExprArg {
23 fn to_tokens(&self, ts: &mut TokenStream2) {
24 self.expr.to_tokens(ts);
25 }
26}
27
28/// A sequence of comma separated expressions wrapped in parentheses (with a trailing comma)
29pub(crate) struct ExprArgs {
30 pub(crate) args: Vec<ExprArg>,
31}
32
33////////////////////////////////////////////////
34
35impl MyParse for ExprArg {
36 fn parse(input: ParseStream<'_>) -> Result<Self, crate::Error> {
37 let paren: Parentheses = input.parse_paren()?;
38
39 let mut content: ParseBuffer = ParseBuffer::new(ts:paren.contents);
40
41 content.parse_unwrap_tt(|content: &mut ParseBuffer| {
42 let (expr: TokenStream, span: Spans) = content.parse_token_stream_and_span();
43
44 Ok(Self { span, expr })
45 })
46 }
47}
48
49////////////////////////////////////////////////
50
51impl MyParse for ExprArgs {
52 fn parse(input: ParseStream<'_>) -> Result<Self, crate::Error> {
53 let mut args: Vec = Vec::new();
54
55 while !input.is_empty() {
56 args.push(ExprArg::parse(input)?);
57
58 if !input.is_empty() {
59 input.parse_punct(',')?;
60 }
61 }
62
63 Ok(Self { args })
64 }
65}
66