runtime_macros_derive

Function emulate_attribute_expansion_fallible

Source
pub fn emulate_attribute_expansion_fallible<Arg, Res>(
    file: File,
    macro_path: &str,
    macro_fn: impl Fn(Arg, Arg) -> Res,
) -> Result<(), Error>
where Arg: From<TokenStream>, Res: Into<TokenStream>,
Expand description

Parses the given Rust source file, finding attributes macro expansions using macro_path. Each time it finds one, it calls derive_fn, passing it a syn::DeriveInput.

Note that this parser only handles Rust’s syntax, so it cannot resolve paths to see if they are equivalent to the given one. The paths used to reference the macro must be exactly equal to the one given in order to be expanded by this function. For example, if macro_path is "foo" and the file provided calls the macro using #[bar::foo], this function will not know to expand it, and the macro’s code coverage will be underestimated. Also it is important, that this function would expand every matching attribute, so it is important to design your macros in the way, the attribute do not collide with other attributes used in tests - not only actual macros, but also attributes eaten by other macros/derives.

This function follows the standard syn pattern of implementing most of the logic using top use quote::quote; use syn::parse_macro_input;

#[proc_macro_attribute] fn hello(attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream { hello_internal(attr.into(), item.into()).into() }

fn hello_internal(attr: proc_macro2::TokenStream, item: proc_macro2::TokenStream) -> proc_macro2::TokenStream { quote!(#item) }

#test fn macro_code_coverage() { let file = std::fs::File::open(“tests/tests.rs”); emulate_attribute_expansion_fallible(file, “hello”, hello_internal); }