1 /// Parse the input TokenStream of a macro, triggering a compile error if the
2 /// tokens fail to parse.
4 /// Refer to the [`parse` module] documentation for more details about parsing
7 /// [`parse` module]: crate::rustdoc_workaround::parse_module
13 /// This macro must be called from a function that returns
14 /// `proc_macro::TokenStream`. Usually this will be your proc macro entry point,
15 /// the function that has the #\[proc_macro\] / #\[proc_macro_derive\] /
16 /// #\[proc_macro_attribute\] attribute.
19 /// # extern crate proc_macro;
21 /// use proc_macro::TokenStream;
22 /// use syn::{parse_macro_input, Result};
23 /// use syn::parse::{Parse, ParseStream};
25 /// struct MyMacroInput {
29 /// impl Parse for MyMacroInput {
30 /// fn parse(input: ParseStream) -> Result<Self> {
32 /// # Ok(MyMacroInput {})
36 /// # const IGNORE: &str = stringify! {
39 /// pub fn my_macro(tokens: TokenStream) -> TokenStream {
40 /// let input = parse_macro_input!(tokens as MyMacroInput);
43 /// # "".parse().unwrap()
49 /// # Usage with Parser
51 /// This macro can also be used with the [`Parser` trait] for types that have
52 /// multiple ways that they can be parsed.
54 /// [`Parser` trait]: crate::rustdoc_workaround::parse_module::Parser
57 /// # extern crate proc_macro;
59 /// # use proc_macro::TokenStream;
60 /// # use syn::{parse_macro_input, Result};
61 /// # use syn::parse::ParseStream;
63 /// # struct MyMacroInput {}
65 /// impl MyMacroInput {
66 /// fn parse_alternate(input: ParseStream) -> Result<Self> {
68 /// # Ok(MyMacroInput {})
72 /// # const IGNORE: &str = stringify! {
75 /// pub fn my_macro(tokens: TokenStream) -> TokenStream {
76 /// let input = parse_macro_input!(tokens with MyMacroInput::parse_alternate);
79 /// # "".parse().unwrap()
87 /// `parse_macro_input!($variable as $Type)` expands to something like:
90 /// # extern crate proc_macro;
92 /// # macro_rules! doc_test {
93 /// # ($variable:ident as $Type:ty) => {
94 /// match syn::parse::<$Type>($variable) {
95 /// Ok(syntax_tree) => syntax_tree,
96 /// Err(err) => return proc_macro::TokenStream::from(err.to_compile_error()),
101 /// # fn test(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
102 /// # let _ = doc_test!(input as syn::Ident);
103 /// # proc_macro::TokenStream::new()
107 macro_rules
! parse_macro_input
{
108 ($tokenstream
:ident
as $ty
:ty
) => {
109 match $
crate::parse_macro_input
::parse
::<$ty
>($tokenstream
) {
110 $
crate::export
::Ok(data
) => data
,
111 $
crate::export
::Err(err
) => {
112 return $
crate::export
::TokenStream
::from(err
.to_compile_error());
116 ($tokenstream
:ident with $parser
:path
) => {
117 match $
crate::parse
::Parser
::parse($parser
, $tokenstream
) {
118 $
crate::export
::Ok(data
) => data
,
119 $
crate::export
::Err(err
) => {
120 return $
crate::export
::TokenStream
::from(err
.to_compile_error());
124 ($tokenstream
:ident
) => {
125 $
crate::parse_macro_input
!($tokenstream
as _
)
129 ////////////////////////////////////////////////////////////////////////////////
130 // Can parse any type that implements Parse.
132 use crate::parse
::{Parse, ParseStream, Parser, Result}
;
133 use proc_macro
::TokenStream
;
137 pub fn parse
<T
: ParseMacroInput
>(token_stream
: TokenStream
) -> Result
<T
> {
138 T
::parse
.parse(token_stream
)
143 pub trait ParseMacroInput
: Sized
{
144 fn parse(input
: ParseStream
) -> Result
<Self>;
147 impl<T
: Parse
> ParseMacroInput
for T
{
148 fn parse(input
: ParseStream
) -> Result
<Self> {
149 <T
as Parse
>::parse(input
)
153 ////////////////////////////////////////////////////////////////////////////////
154 // Any other types that we want `parse_macro_input!` to be able to parse.
156 #[cfg(any(feature = "full", feature = "derive"))]
157 use crate::AttributeArgs
;
159 #[cfg(any(feature = "full", feature = "derive"))]
160 impl ParseMacroInput
for AttributeArgs
{
161 fn parse(input
: ParseStream
) -> Result
<Self> {
162 let mut metas
= Vec
::new();
165 if input
.is_empty() {
168 let value
= input
.parse()?
;
170 if input
.is_empty() {
173 input
.parse
::<Token
![,]>()?
;