| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- // SPDX-License-Identifier: Apache-2.0 OR MIT
- use crate::error::Result;
- use crate::parse::ParseBuffer;
- use crate::token;
- use proc_macro2::extra::DelimSpan;
- use proc_macro2::Delimiter;
- // Not public API.
- #[doc(hidden)]
- pub struct Parens<'a> {
- #[doc(hidden)]
- pub token: token::Paren,
- #[doc(hidden)]
- pub content: ParseBuffer<'a>,
- }
- // Not public API.
- #[doc(hidden)]
- pub struct Braces<'a> {
- #[doc(hidden)]
- pub token: token::Brace,
- #[doc(hidden)]
- pub content: ParseBuffer<'a>,
- }
- // Not public API.
- #[doc(hidden)]
- pub struct Brackets<'a> {
- #[doc(hidden)]
- pub token: token::Bracket,
- #[doc(hidden)]
- pub content: ParseBuffer<'a>,
- }
- // Not public API.
- #[cfg(any(feature = "full", feature = "derive"))]
- #[doc(hidden)]
- pub struct Group<'a> {
- #[doc(hidden)]
- pub token: token::Group,
- #[doc(hidden)]
- pub content: ParseBuffer<'a>,
- }
- // Not public API.
- #[doc(hidden)]
- pub fn parse_parens<'a>(input: &ParseBuffer<'a>) -> Result<Parens<'a>> {
- parse_delimited(input, Delimiter::Parenthesis).map(|(span, content)| Parens {
- token: token::Paren(span),
- content,
- })
- }
- // Not public API.
- #[doc(hidden)]
- pub fn parse_braces<'a>(input: &ParseBuffer<'a>) -> Result<Braces<'a>> {
- parse_delimited(input, Delimiter::Brace).map(|(span, content)| Braces {
- token: token::Brace(span),
- content,
- })
- }
- // Not public API.
- #[doc(hidden)]
- pub fn parse_brackets<'a>(input: &ParseBuffer<'a>) -> Result<Brackets<'a>> {
- parse_delimited(input, Delimiter::Bracket).map(|(span, content)| Brackets {
- token: token::Bracket(span),
- content,
- })
- }
- #[cfg(any(feature = "full", feature = "derive"))]
- pub(crate) fn parse_group<'a>(input: &ParseBuffer<'a>) -> Result<Group<'a>> {
- parse_delimited(input, Delimiter::None).map(|(span, content)| Group {
- token: token::Group(span.join()),
- content,
- })
- }
- fn parse_delimited<'a>(
- input: &ParseBuffer<'a>,
- delimiter: Delimiter,
- ) -> Result<(DelimSpan, ParseBuffer<'a>)> {
- input.step(|cursor| {
- if let Some((content, span, rest)) = cursor.group(delimiter) {
- let scope = span.close();
- let nested = crate::parse::advance_step_cursor(cursor, content);
- let unexpected = crate::parse::get_unexpected(input);
- let content = crate::parse::new_parse_buffer(scope, nested, unexpected);
- Ok(((span, content), rest))
- } else {
- let message = match delimiter {
- Delimiter::Parenthesis => "expected parentheses",
- Delimiter::Brace => "expected curly braces",
- Delimiter::Bracket => "expected square brackets",
- Delimiter::None => "expected invisible group",
- };
- Err(cursor.error(message))
- }
- })
- }
- /// Parse a set of parentheses and expose their content to subsequent parsers.
- ///
- /// # Example
- ///
- /// ```
- /// # use quote::quote;
- /// #
- /// use syn::{parenthesized, token, Ident, Result, Token, Type};
- /// use syn::parse::{Parse, ParseStream};
- /// use syn::punctuated::Punctuated;
- ///
- /// // Parse a simplified tuple struct syntax like:
- /// //
- /// // struct S(A, B);
- /// struct TupleStruct {
- /// struct_token: Token![struct],
- /// ident: Ident,
- /// paren_token: token::Paren,
- /// fields: Punctuated<Type, Token![,]>,
- /// semi_token: Token![;],
- /// }
- ///
- /// impl Parse for TupleStruct {
- /// fn parse(input: ParseStream) -> Result<Self> {
- /// let content;
- /// Ok(TupleStruct {
- /// struct_token: input.parse()?,
- /// ident: input.parse()?,
- /// paren_token: parenthesized!(content in input),
- /// fields: content.parse_terminated(Type::parse, Token![,])?,
- /// semi_token: input.parse()?,
- /// })
- /// }
- /// }
- /// #
- /// # fn main() {
- /// # let input = quote! {
- /// # struct S(A, B);
- /// # };
- /// # syn::parse2::<TupleStruct>(input).unwrap();
- /// # }
- /// ```
- #[macro_export]
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- macro_rules! parenthesized {
- ($content:ident in $cursor:expr) => {
- match $crate::__private::parse_parens(&$cursor) {
- $crate::__private::Ok(parens) => {
- $content = parens.content;
- parens.token
- }
- $crate::__private::Err(error) => {
- return $crate::__private::Err(error);
- }
- }
- };
- }
- /// Parse a set of curly braces and expose their content to subsequent parsers.
- ///
- /// # Example
- ///
- /// ```
- /// # use quote::quote;
- /// #
- /// use syn::{braced, token, Ident, Result, Token, Type};
- /// use syn::parse::{Parse, ParseStream};
- /// use syn::punctuated::Punctuated;
- ///
- /// // Parse a simplified struct syntax like:
- /// //
- /// // struct S {
- /// // a: A,
- /// // b: B,
- /// // }
- /// struct Struct {
- /// struct_token: Token![struct],
- /// ident: Ident,
- /// brace_token: token::Brace,
- /// fields: Punctuated<Field, Token![,]>,
- /// }
- ///
- /// struct Field {
- /// name: Ident,
- /// colon_token: Token![:],
- /// ty: Type,
- /// }
- ///
- /// impl Parse for Struct {
- /// fn parse(input: ParseStream) -> Result<Self> {
- /// let content;
- /// Ok(Struct {
- /// struct_token: input.parse()?,
- /// ident: input.parse()?,
- /// brace_token: braced!(content in input),
- /// fields: content.parse_terminated(Field::parse, Token![,])?,
- /// })
- /// }
- /// }
- ///
- /// impl Parse for Field {
- /// fn parse(input: ParseStream) -> Result<Self> {
- /// Ok(Field {
- /// name: input.parse()?,
- /// colon_token: input.parse()?,
- /// ty: input.parse()?,
- /// })
- /// }
- /// }
- /// #
- /// # fn main() {
- /// # let input = quote! {
- /// # struct S {
- /// # a: A,
- /// # b: B,
- /// # }
- /// # };
- /// # syn::parse2::<Struct>(input).unwrap();
- /// # }
- /// ```
- #[macro_export]
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- macro_rules! braced {
- ($content:ident in $cursor:expr) => {
- match $crate::__private::parse_braces(&$cursor) {
- $crate::__private::Ok(braces) => {
- $content = braces.content;
- braces.token
- }
- $crate::__private::Err(error) => {
- return $crate::__private::Err(error);
- }
- }
- };
- }
- /// Parse a set of square brackets and expose their content to subsequent
- /// parsers.
- ///
- /// # Example
- ///
- /// ```
- /// # use quote::quote;
- /// #
- /// use proc_macro2::TokenStream;
- /// use syn::{bracketed, token, Result, Token};
- /// use syn::parse::{Parse, ParseStream};
- ///
- /// // Parse an outer attribute like:
- /// //
- /// // #[repr(C, packed)]
- /// struct OuterAttribute {
- /// pound_token: Token![#],
- /// bracket_token: token::Bracket,
- /// content: TokenStream,
- /// }
- ///
- /// impl Parse for OuterAttribute {
- /// fn parse(input: ParseStream) -> Result<Self> {
- /// let content;
- /// Ok(OuterAttribute {
- /// pound_token: input.parse()?,
- /// bracket_token: bracketed!(content in input),
- /// content: content.parse()?,
- /// })
- /// }
- /// }
- /// #
- /// # fn main() {
- /// # let input = quote! {
- /// # #[repr(C, packed)]
- /// # };
- /// # syn::parse2::<OuterAttribute>(input).unwrap();
- /// # }
- /// ```
- #[macro_export]
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- macro_rules! bracketed {
- ($content:ident in $cursor:expr) => {
- match $crate::__private::parse_brackets(&$cursor) {
- $crate::__private::Ok(brackets) => {
- $content = brackets.content;
- brackets.token
- }
- $crate::__private::Err(error) => {
- return $crate::__private::Err(error);
- }
- }
- };
- }
|