1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
// SPDX-License-Identifier: Apache-2.0 OR MIT
/// Parse the input TokenStream of a macro, triggering a compile error if the
/// tokens fail to parse.
///
/// Refer to the [`parse` module] documentation for more details about parsing
/// in Syn.
///
/// [`parse` module]: mod@crate::parse
///
/// <br>
///
/// # Intended usage
///
/// This macro must be called from a function that returns
/// `proc_macro::TokenStream`. Usually this will be your proc macro entry point,
/// the function that has the #\[proc_macro\] / #\[proc_macro_derive\] /
/// #\[proc_macro_attribute\] attribute.
///
/// ```
/// # extern crate proc_macro;
/// #
/// use proc_macro::TokenStream;
/// use syn::{parse_macro_input, Result};
/// use syn::parse::{Parse, ParseStream};
///
/// struct MyMacroInput {
/// /* ... */
/// }
///
/// impl Parse for MyMacroInput {
/// fn parse(input: ParseStream) -> Result<Self> {
/// /* ... */
/// # Ok(MyMacroInput {})
/// }
/// }
///
/// # const IGNORE: &str = stringify! {
/// #[proc_macro]
/// # };
/// pub fn my_macro(tokens: TokenStream) -> TokenStream {
/// let input = parse_macro_input!(tokens as MyMacroInput);
///
/// /* ... */
/// # TokenStream::new()
/// }
/// ```
///
/// <br>
///
/// # Usage with Parser
///
/// This macro can also be used with the [`Parser` trait] for types that have
/// multiple ways that they can be parsed.
///
/// [`Parser` trait]: crate::parse::Parser
///
/// ```
/// # extern crate proc_macro;
/// #
/// # use proc_macro::TokenStream;
/// # use syn::{parse_macro_input, Result};
/// # use syn::parse::ParseStream;
/// #
/// # struct MyMacroInput {}
/// #
/// impl MyMacroInput {
/// fn parse_alternate(input: ParseStream) -> Result<Self> {
/// /* ... */
/// # Ok(MyMacroInput {})
/// }
/// }
///
/// # const IGNORE: &str = stringify! {
/// #[proc_macro]
/// # };
/// pub fn my_macro(tokens: TokenStream) -> TokenStream {
/// let input = parse_macro_input!(tokens with MyMacroInput::parse_alternate);
///
/// /* ... */
/// # TokenStream::new()
/// }
/// ```
///
/// <br>
///
/// # Expansion
///
/// `parse_macro_input!($variable as $Type)` expands to something like:
///
/// ```no_run
/// # extern crate proc_macro;
/// #
/// # macro_rules! doc_test {
/// # ($variable:ident as $Type:ty) => {
/// match syn::parse::<$Type>($variable) {
/// Ok(syntax_tree) => syntax_tree,
/// Err(err) => return proc_macro::TokenStream::from(err.to_compile_error()),
/// }
/// # };
/// # }
/// #
/// # fn test(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
/// # let _ = doc_test!(input as syn::Ident);
/// # proc_macro::TokenStream::new()
/// # }
/// ```
#[macro_export]
#[cfg_attr(docsrs, doc(cfg(all(feature = "parsing", feature = "proc-macro"))))]
macro_rules! parse_macro_input {
($tokenstream:ident as $ty:ty) => {
match $crate::parse::<$ty>($tokenstream) {
$crate::__private::Ok(data) => data,
$crate::__private::Err(err) => {
return $crate::__private::TokenStream::from(err.to_compile_error());
}
}
};
($tokenstream:ident with $parser:path) => {
match $crate::parse::Parser::parse($parser, $tokenstream) {
$crate::__private::Ok(data) => data,
$crate::__private::Err(err) => {
return $crate::__private::TokenStream::from(err.to_compile_error());
}
}
};
($tokenstream:ident) => {
$crate::parse_macro_input!($tokenstream as _)
};
}
|