File Index
Files and directories
Sign in
FILE

group.rs

File preview with syntax highlighting.

linux-6.19.14/rust/syn/group.rs RUST
  1// SPDX-License-Identifier: Apache-2.0 OR MIT
  2
  3use crate::error::Result;
  4use crate::parse::ParseBuffer;
  5use crate::token;
  6use proc_macro2::extra::DelimSpan;
  7use proc_macro2::Delimiter;
  8
  9// Not public API.
 10#[doc(hidden)]
 11pub struct Parens<'a> {
 12    #[doc(hidden)]
 13    pub token: token::Paren,
 14    #[doc(hidden)]
 15    pub content: ParseBuffer<'a>,
 16}
 17
 18// Not public API.
 19#[doc(hidden)]
 20pub struct Braces<'a> {
 21    #[doc(hidden)]
 22    pub token: token::Brace,
 23    #[doc(hidden)]
 24    pub content: ParseBuffer<'a>,
 25}
 26
 27// Not public API.
 28#[doc(hidden)]
 29pub struct Brackets<'a> {
 30    #[doc(hidden)]
 31    pub token: token::Bracket,
 32    #[doc(hidden)]
 33    pub content: ParseBuffer<'a>,
 34}
 35
 36// Not public API.
 37#[cfg(any(feature = "full", feature = "derive"))]
 38#[doc(hidden)]
 39pub struct Group<'a> {
 40    #[doc(hidden)]
 41    pub token: token::Group,
 42    #[doc(hidden)]
 43    pub content: ParseBuffer<'a>,
 44}
 45
 46// Not public API.
 47#[doc(hidden)]
 48pub fn parse_parens<'a>(input: &ParseBuffer<'a>) -> Result<Parens<'a>> {
 49    parse_delimited(input, Delimiter::Parenthesis).map(|(span, content)| Parens {
 50        token: token::Paren(span),
 51        content,
 52    })
 53}
 54
 55// Not public API.
 56#[doc(hidden)]
 57pub fn parse_braces<'a>(input: &ParseBuffer<'a>) -> Result<Braces<'a>> {
 58    parse_delimited(input, Delimiter::Brace).map(|(span, content)| Braces {
 59        token: token::Brace(span),
 60        content,
 61    })
 62}
 63
 64// Not public API.
 65#[doc(hidden)]
 66pub fn parse_brackets<'a>(input: &ParseBuffer<'a>) -> Result<Brackets<'a>> {
 67    parse_delimited(input, Delimiter::Bracket).map(|(span, content)| Brackets {
 68        token: token::Bracket(span),
 69        content,
 70    })
 71}
 72
 73#[cfg(any(feature = "full", feature = "derive"))]
 74pub(crate) fn parse_group<'a>(input: &ParseBuffer<'a>) -> Result<Group<'a>> {
 75    parse_delimited(input, Delimiter::None).map(|(span, content)| Group {
 76        token: token::Group(span.join()),
 77        content,
 78    })
 79}
 80
 81fn parse_delimited<'a>(
 82    input: &ParseBuffer<'a>,
 83    delimiter: Delimiter,
 84) -> Result<(DelimSpan, ParseBuffer<'a>)> {
 85    input.step(|cursor| {
 86        if let Some((content, span, rest)) = cursor.group(delimiter) {
 87            let scope = span.close();
 88            let nested = crate::parse::advance_step_cursor(cursor, content);
 89            let unexpected = crate::parse::get_unexpected(input);
 90            let content = crate::parse::new_parse_buffer(scope, nested, unexpected);
 91            Ok(((span, content), rest))
 92        } else {
 93            let message = match delimiter {
 94                Delimiter::Parenthesis => "expected parentheses",
 95                Delimiter::Brace => "expected curly braces",
 96                Delimiter::Bracket => "expected square brackets",
 97                Delimiter::None => "expected invisible group",
 98            };
 99            Err(cursor.error(message))
100        }
101    })
102}
103
104/// Parse a set of parentheses and expose their content to subsequent parsers.
105///
106/// # Example
107///
108/// ```
109/// # use quote::quote;
110/// #
111/// use syn::{parenthesized, token, Ident, Result, Token, Type};
112/// use syn::parse::{Parse, ParseStream};
113/// use syn::punctuated::Punctuated;
114///
115/// // Parse a simplified tuple struct syntax like:
116/// //
117/// //     struct S(A, B);
118/// struct TupleStruct {
119///     struct_token: Token![struct],
120///     ident: Ident,
121///     paren_token: token::Paren,
122///     fields: Punctuated<Type, Token![,]>,
123///     semi_token: Token![;],
124/// }
125///
126/// impl Parse for TupleStruct {
127///     fn parse(input: ParseStream) -> Result<Self> {
128///         let content;
129///         Ok(TupleStruct {
130///             struct_token: input.parse()?,
131///             ident: input.parse()?,
132///             paren_token: parenthesized!(content in input),
133///             fields: content.parse_terminated(Type::parse, Token![,])?,
134///             semi_token: input.parse()?,
135///         })
136///     }
137/// }
138/// #
139/// # fn main() {
140/// #     let input = quote! {
141/// #         struct S(A, B);
142/// #     };
143/// #     syn::parse2::<TupleStruct>(input).unwrap();
144/// # }
145/// ```
146#[macro_export]
147#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
148macro_rules! parenthesized {
149    ($content:ident in $cursor:expr) => {
150        match $crate::__private::parse_parens(&$cursor) {
151            $crate::__private::Ok(parens) => {
152                $content = parens.content;
153                parens.token
154            }
155            $crate::__private::Err(error) => {
156                return $crate::__private::Err(error);
157            }
158        }
159    };
160}
161
162/// Parse a set of curly braces and expose their content to subsequent parsers.
163///
164/// # Example
165///
166/// ```
167/// # use quote::quote;
168/// #
169/// use syn::{braced, token, Ident, Result, Token, Type};
170/// use syn::parse::{Parse, ParseStream};
171/// use syn::punctuated::Punctuated;
172///
173/// // Parse a simplified struct syntax like:
174/// //
175/// //     struct S {
176/// //         a: A,
177/// //         b: B,
178/// //     }
179/// struct Struct {
180///     struct_token: Token![struct],
181///     ident: Ident,
182///     brace_token: token::Brace,
183///     fields: Punctuated<Field, Token![,]>,
184/// }
185///
186/// struct Field {
187///     name: Ident,
188///     colon_token: Token![:],
189///     ty: Type,
190/// }
191///
192/// impl Parse for Struct {
193///     fn parse(input: ParseStream) -> Result<Self> {
194///         let content;
195///         Ok(Struct {
196///             struct_token: input.parse()?,
197///             ident: input.parse()?,
198///             brace_token: braced!(content in input),
199///             fields: content.parse_terminated(Field::parse, Token![,])?,
200///         })
201///     }
202/// }
203///
204/// impl Parse for Field {
205///     fn parse(input: ParseStream) -> Result<Self> {
206///         Ok(Field {
207///             name: input.parse()?,
208///             colon_token: input.parse()?,
209///             ty: input.parse()?,
210///         })
211///     }
212/// }
213/// #
214/// # fn main() {
215/// #     let input = quote! {
216/// #         struct S {
217/// #             a: A,
218/// #             b: B,
219/// #         }
220/// #     };
221/// #     syn::parse2::<Struct>(input).unwrap();
222/// # }
223/// ```
224#[macro_export]
225#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
226macro_rules! braced {
227    ($content:ident in $cursor:expr) => {
228        match $crate::__private::parse_braces(&$cursor) {
229            $crate::__private::Ok(braces) => {
230                $content = braces.content;
231                braces.token
232            }
233            $crate::__private::Err(error) => {
234                return $crate::__private::Err(error);
235            }
236        }
237    };
238}
239
240/// Parse a set of square brackets and expose their content to subsequent
241/// parsers.
242///
243/// # Example
244///
245/// ```
246/// # use quote::quote;
247/// #
248/// use proc_macro2::TokenStream;
249/// use syn::{bracketed, token, Result, Token};
250/// use syn::parse::{Parse, ParseStream};
251///
252/// // Parse an outer attribute like:
253/// //
254/// //     #[repr(C, packed)]
255/// struct OuterAttribute {
256///     pound_token: Token![#],
257///     bracket_token: token::Bracket,
258///     content: TokenStream,
259/// }
260///
261/// impl Parse for OuterAttribute {
262///     fn parse(input: ParseStream) -> Result<Self> {
263///         let content;
264///         Ok(OuterAttribute {
265///             pound_token: input.parse()?,
266///             bracket_token: bracketed!(content in input),
267///             content: content.parse()?,
268///         })
269///     }
270/// }
271/// #
272/// # fn main() {
273/// #     let input = quote! {
274/// #         #[repr(C, packed)]
275/// #     };
276/// #     syn::parse2::<OuterAttribute>(input).unwrap();
277/// # }
278/// ```
279#[macro_export]
280#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
281macro_rules! bracketed {
282    ($content:ident in $cursor:expr) => {
283        match $crate::__private::parse_brackets(&$cursor) {
284            $crate::__private::Ok(brackets) => {
285                $content = brackets.content;
286                brackets.token
287            }
288            $crate::__private::Err(error) => {
289                return $crate::__private::Err(error);
290            }
291        }
292    };
293}
~/ Read-only file preview.