|
1 | 1 | use proc_macro::TokenStream; |
2 | 2 | use proc_macro2::TokenStream as TokenStream2; |
3 | 3 | use quote::quote; |
4 | | -use syn::{parse2, ItemFn, ItemMod}; |
| 4 | +use syn::{parse_macro_input, Item}; |
5 | 5 |
|
6 | 6 | /// An exposed test. This is a test that will run locally and also be |
7 | 7 | /// made available to other crates that want to run it in their own context. |
@@ -40,34 +40,41 @@ use syn::{parse2, ItemFn, ItemMod}; |
40 | 40 | /// is on. |
41 | 41 | #[proc_macro_attribute] |
42 | 42 | pub fn xtest(attrs: TokenStream, item: TokenStream) -> TokenStream { |
43 | | - let input = syn::parse_macro_input!(item as TokenStream2); |
44 | | - let attrs = syn::parse_macro_input!(attrs as TokenStream2); |
| 43 | + let attrs = parse_macro_input!(attrs as TokenStream2); |
| 44 | + let input = parse_macro_input!(item as Item); |
45 | 45 |
|
46 | | - let expanded = if is_module_definition(input.clone()) { |
47 | | - let cfg = if attrs.is_empty() { |
48 | | - quote! { #[cfg(test)] } |
49 | | - } else { |
50 | | - quote! { #[cfg(any(test, #attrs))] } |
51 | | - }; |
52 | | - quote! { |
53 | | - #cfg |
54 | | - #input |
| 46 | + let expanded = match input { |
| 47 | + Item::Mod(item_mod) => { |
| 48 | + let cfg = if attrs.is_empty() { |
| 49 | + quote! { #[cfg(test)] } |
| 50 | + } else { |
| 51 | + quote! { #[cfg(any(test, #attrs))] } |
| 52 | + }; |
| 53 | + quote! { |
| 54 | + #cfg |
| 55 | + #item_mod |
| 56 | + } |
55 | 57 | } |
56 | | - } else if is_function_definition(input.clone()) { |
57 | | - quote! { |
58 | | - #[cfg_attr(test, ::core::prelude::v1::test)] |
59 | | - #input |
| 58 | + Item::Fn(item_fn) => { |
| 59 | + let cfg_attr = if attrs.is_empty() { |
| 60 | + quote! { #[cfg(test)] } |
| 61 | + } else { |
| 62 | + quote! { #[cfg(any(test, #attrs))] } |
| 63 | + }; |
| 64 | + quote! { |
| 65 | + #cfg_attr |
| 66 | + #item_fn |
| 67 | + } |
| 68 | + } |
| 69 | + _ => { |
| 70 | + return syn::Error::new_spanned( |
| 71 | + input, |
| 72 | + "xtest can only be applied to functions or modules", |
| 73 | + ) |
| 74 | + .to_compile_error() |
| 75 | + .into(); |
60 | 76 | } |
61 | | - } else { |
62 | | - panic!("xtest can only be applied to functions or modules"); |
63 | 77 | }; |
64 | | - expanded.into() |
65 | | -} |
66 | | - |
67 | | -fn is_module_definition(input: TokenStream2) -> bool { |
68 | | - parse2::<ItemMod>(input).is_ok() |
69 | | -} |
70 | 78 |
|
71 | | -fn is_function_definition(input: TokenStream2) -> bool { |
72 | | - parse2::<ItemFn>(input).is_ok() |
| 79 | + TokenStream::from(expanded) |
73 | 80 | } |
0 commit comments