293 lines · 7.7 KB · Rust
RawDownload
// 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);            }        }    };}