parse_macro_input.rs 3.5 KB

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