summaryrefslogtreecommitdiff
path: root/rust/syn/parse_macro_input.rs
diff options
context:
space:
mode:
authorMiguel Ojeda <ojeda@kernel.org>2025-11-24 16:18:27 +0100
committerMiguel Ojeda <ojeda@kernel.org>2025-11-24 17:15:44 +0100
commit808c999fc9e7c366fd47da564e69d579c1dc8279 (patch)
treed81985de64150acef12e038e98ef950e1b41b2d6 /rust/syn/parse_macro_input.rs
parent88de91cc1ce7b3069ccabc1a5fbe16d41c663093 (diff)
rust: syn: import crate
This is a subset of the Rust `syn` crate, version 2.0.106 (released 2025-08-16), licensed under "Apache-2.0 OR MIT", from: https://github.com/dtolnay/syn/raw/2.0.106/src The files are copied as-is, with no modifications whatsoever (not even adding the SPDX identifiers). For copyright details, please see: https://github.com/dtolnay/syn/blob/2.0.106/README.md#license https://github.com/dtolnay/syn/blob/2.0.106/LICENSE-APACHE https://github.com/dtolnay/syn/blob/2.0.106/LICENSE-MIT The next two patches modify these files as needed for use within the kernel. This patch split allows reviewers to double-check the import and to clearly see the differences introduced. The following script may be used to verify the contents: for path in $(cd rust/syn/ && find . -type f -name '*.rs'); do curl --silent --show-error --location \ https://github.com/dtolnay/syn/raw/2.0.106/src/$path \ | diff --unified rust/syn/$path - && echo $path: OK done Reviewed-by: Gary Guo <gary@garyguo.net> Tested-by: Gary Guo <gary@garyguo.net> Tested-by: Jesung Yang <y.j3ms.n@gmail.com> Link: https://patch.msgid.link/20251124151837.2184382-16-ojeda@kernel.org Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'rust/syn/parse_macro_input.rs')
-rw-r--r--rust/syn/parse_macro_input.rs128
1 files changed, 128 insertions, 0 deletions
diff --git a/rust/syn/parse_macro_input.rs b/rust/syn/parse_macro_input.rs
new file mode 100644
index 000000000000..f0660aedd7df
--- /dev/null
+++ b/rust/syn/parse_macro_input.rs
@@ -0,0 +1,128 @@
+/// 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 _)
+ };
+}