syn_error_experiment/
group.rs

1use proc_macro2::Delimiter;
2
3use parse::{ParseBuffer, Result};
4use token;
5
6pub struct Braces<'a> {
7    pub token: token::Brace,
8    pub content: ParseBuffer<'a>,
9}
10
11impl<'a> ParseBuffer<'a> {
12    // Not public API.
13    #[doc(hidden)]
14    pub fn parse_braces(&self) -> Result<Braces<'a>> {
15        self.step_cursor(|cursor| {
16            if let Some((content, span, rest)) = cursor.group(Delimiter::Brace) {
17                let braces = Braces {
18                    token: token::Brace(span),
19                    content: ParseBuffer::new(span, cursor.advance(content)),
20                };
21                Ok((braces, rest))
22            } else {
23                Err(cursor.error("expected curly braces"))
24            }
25        })
26    }
27}
28
29/// Parse a set of curly braces and expose their content to subsequent parsers.
30///
31/// ```rust
32/// # extern crate syn_error_experiment;
33/// #
34/// use syn_error_experiment::{braced, token, Ident, Token};
35/// use syn_error_experiment::parse::{Parse, ParseStream, Result};
36/// # use syn_error_experiment::Field;
37///
38/// // Parse a simplified struct syntax like:
39/// //
40/// //     struct S {
41/// //         a: A,
42/// //         b: B,
43/// //     }
44/// struct Struct {
45///     pub struct_token: Token![struct],
46///     pub ident: Ident,
47///     pub brace_token: token::Brace,
48///     pub fields: Vec<Field>,
49/// }
50///
51/// impl Parse for Struct {
52///     fn parse(input: ParseStream) -> Result<Self> {
53///         let content;
54///         Ok(Struct {
55///             struct_token: input.parse()?,
56///             ident: input.parse()?,
57///             brace_token: braced!(content in input),
58///             fields: content.parse()?,
59///         })
60///     }
61/// }
62/// ```
63#[macro_export]
64macro_rules! braced {
65    ($content:ident in $cursor:expr) => {
66        match $crate::parse::ParseBuffer::parse_braces(&$cursor) {
67            $crate::export::Ok(braces) => {
68                $content = braces.content;
69                braces.token
70            }
71            $crate::export::Err(error) => {
72                return $crate::export::Err(error);
73            }
74        }
75    };
76}