syn/
parse_macro_input.rs

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/// #   TokenStream::new()
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/// #   TokenStream::new()
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(docsrs, doc(cfg(all(feature = "parsing", feature = "proc-macro"))))]
108macro_rules! parse_macro_input {
109    ($tokenstream:ident as $ty:ty) => {
110        match $crate::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}