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