blob: dca4d1c714d30bc8fac3ab758fa73054bf11d6ab [file] [log] [blame]
David Tolnay18c754c2018-08-21 23:26:58 -04001use proc_macro2::Delimiter;
2
David Tolnay544a90f2018-08-24 20:34:03 -04003use super::parse::{ParseBuffer, Result};
4use super::token;
David Tolnay18c754c2018-08-21 23:26:58 -04005
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) => {
David Tolnay544a90f2018-08-24 20:34:03 -040066 match $crate::next::parse::ParseBuffer::parse_braces(&$cursor) {
67 $crate::next::export::Ok(braces) => {
David Tolnay18c754c2018-08-21 23:26:58 -040068 $content = braces.content;
69 braces.token
70 }
David Tolnay544a90f2018-08-24 20:34:03 -040071 $crate::next::export::Err(error) => {
72 return $crate::next::export::Err(error);
David Tolnay18c754c2018-08-21 23:26:58 -040073 }
74 }
75 };
76}