From 31d46824e53ccb24eb5dbaec35993229b033e221 Mon Sep 17 00:00:00 2001 From: Bryan Henry Date: Sun, 13 Sep 2020 23:32:17 -0700 Subject: [PATCH] Add case to parse_macro_input! to use a Parser function --- src/parse_macro_input.rs | 45 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/parse_macro_input.rs b/src/parse_macro_input.rs index c8fc1cea37..cde74c952e 100644 --- a/src/parse_macro_input.rs +++ b/src/parse_macro_input.rs @@ -46,6 +46,42 @@ /// ///
/// +/// # 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::rustdoc_workaround::parse_module::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 { +/// /* ... */ +/// # 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); +/// +/// /* ... */ +/// # "".parse().unwrap() +/// } +/// ``` +/// +///
+/// /// # Expansion /// /// `parse_macro_input!($variable as $Type)` expands to something like: @@ -80,6 +116,15 @@ macro_rules! parse_macro_input { ($tokenstream:ident) => { $crate::parse_macro_input!($tokenstream as _) }; + ($tokenstream:ident with $parser:path) => {{ + use $crate::parse::Parser; + match $parser.parse($tokenstream) { + $crate::export::Ok(data) => data, + $crate::export::Err(err) => { + return $crate::export::TokenStream::from(err.to_compile_error()); + } + } + }}; } ////////////////////////////////////////////////////////////////////////////////