1/// Parse the input TokenStream of a macro, triggering a compile error if the
2/// tokens fail to parse.
3///
4/// Refer to the [`parse` module] documentation for more details about parsing
5/// in Syn.
6///
7/// [`parse` module]: mod@crate::parse
8///
9/// <br>
10///
11/// # Intended usage
12///
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.
17///
18/// ```
19/// # extern crate proc_macro;
20/// #
21/// use proc_macro::TokenStream;
22/// use syn::{parse_macro_input, Result};
23/// use syn::parse::{Parse, ParseStream};
24///
25/// struct MyMacroInput {
26/// /* ... */
27/// }
28///
29/// impl Parse for MyMacroInput {
30/// fn parse(input: ParseStream) -> Result<Self> {
31/// /* ... */
32/// # Ok(MyMacroInput {})
33/// }
34/// }
35///
36/// # const IGNORE: &str = stringify! {
37/// #[proc_macro]
38/// # };
39/// pub fn my_macro(tokens: TokenStream) -> TokenStream {
40/// let input = parse_macro_input!(tokens as MyMacroInput);
41///
42/// /* ... */
43/// # "".parse().unwrap()
44/// }
45/// ```
46///
47/// <br>
48///
49/// # Usage with Parser
50///
51/// This macro can also be used with the [`Parser` trait] for types that have
52/// multiple ways that they can be parsed.
53///
54/// [`Parser` trait]: crate::parse::Parser
55///
56/// ```
57/// # extern crate proc_macro;
58/// #
59/// # use proc_macro::TokenStream;
60/// # use syn::{parse_macro_input, Result};
61/// # use syn::parse::ParseStream;
62/// #
63/// # struct MyMacroInput {}
64/// #
65/// impl MyMacroInput {
66/// fn parse_alternate(input: ParseStream) -> Result<Self> {
67/// /* ... */
68/// # Ok(MyMacroInput {})
69/// }
70/// }
71///
72/// # const IGNORE: &str = stringify! {
73/// #[proc_macro]
74/// # };
75/// pub fn my_macro(tokens: TokenStream) -> TokenStream {
76/// let input = parse_macro_input!(tokens with MyMacroInput::parse_alternate);
77///
78/// /* ... */
79/// # "".parse().unwrap()
80/// }
81/// ```
82///
83/// <br>
84///
85/// # Expansion
86///
87/// `parse_macro_input!($variable as $Type)` expands to something like:
88///
89/// ```no_run
90/// # extern crate proc_macro;
91/// #
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()),
97/// }
98/// # };
99/// # }
100/// #
101/// # fn test(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
102/// # let _ = doc_test!(input as syn::Ident);
103/// # proc_macro::TokenStream::new()
104/// # }
105/// ```
106#[macro_export]
107#[cfg_attr(doc_cfg, doc(cfg(all(feature = "parsing", feature = "proc-macro"))))]
108macro_rules! parse_macro_input {
109 ($tokenstream:ident as $ty:ty) => {
110 match $crate::parse_macro_input::parse::<$ty>($tokenstream) {
111 $crate::__private::Ok(data) => data,
112 $crate::__private::Err(err) => {
113 return $crate::__private::TokenStream::from(err.to_compile_error());
114 }
115 }
116 };
117 ($tokenstream:ident with $parser:path) => {
118 match $crate::parse::Parser::parse($parser, $tokenstream) {
119 $crate::__private::Ok(data) => data,
120 $crate::__private::Err(err) => {
121 return $crate::__private::TokenStream::from(err.to_compile_error());
122 }
123 }
124 };
125 ($tokenstream:ident) => {
126 $crate::parse_macro_input!($tokenstream as _)
127 };
128}
129
130////////////////////////////////////////////////////////////////////////////////
131// Can parse any type that implements Parse.
132
133use crate::parse::{Parse, ParseStream, Parser, Result};
134use proc_macro::TokenStream;
135
136// Not public API.
137#[doc(hidden)]
138pub fn parse<T: ParseMacroInput>(token_stream: TokenStream) -> Result<T> {
139 T::parse.parse(token_stream)
140}
141
142// Not public API.
143#[doc(hidden)]
144pub trait ParseMacroInput: Sized {
145 fn parse(input: ParseStream) -> Result<Self>;
146}
147
148impl<T: Parse> ParseMacroInput for T {
149 fn parse(input: ParseStream) -> Result<Self> {
150 <T as Parse>::parse(input)
151 }
152}
153
154////////////////////////////////////////////////////////////////////////////////
155// Any other types that we want `parse_macro_input!` to be able to parse.
156
157#[cfg(any(feature = "full", feature = "derive"))]
158use crate::AttributeArgs;
159
160#[cfg(any(feature = "full", feature = "derive"))]
161impl ParseMacroInput for AttributeArgs {
162 fn parse(input: ParseStream) -> Result<Self> {
163 let mut metas = Vec::new();
164
165 loop {
166 if input.is_empty() {
167 break;
168 }
169 let value = input.parse()?;
170 metas.push(value);
171 if input.is_empty() {
172 break;
173 }
174 input.parse::<Token![,]>()?;
175 }
176
177 Ok(metas)
178 }
179}
180