[][src]Function runtime_macros_derive::emulate_derive_expansion_fallible

pub fn emulate_derive_expansion_fallible<F>(
    file: File,
    macro_path: &str,
    derive_fn: F
) -> Result<(), Error> where
    F: Fn(DeriveInput) -> TokenStream

Parses the given Rust source file, finding custom drives 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.

This function follows the standard syn pattern of implementing most of the logic using the proc_macro2 types, leaving only those methods that can only exist for proc_macro=true crates, such as types from proc_macro or syn::parse_macro_input in the outer function. This allows use of the inner function in tests which is needed to expand it here.

Returns

Ok on success, or an instance of Error indicating any error that occurred when trying to read or parse the file.

Example

This example is not tested
 
use quote::quote;
use syn::parse_macro_input;
 
#[proc_macro_derive(Hello)]
fn hello(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    hello_internal(parse_macro_input!(input as DeriveInput)).into()
}
 
fn hello_internal(input: syn::DeriveInput) -> proc_macro2::TokenStream {
    let ident = input.ident;
    quote! {
        impl #ident {
            fn hello_world() -> String {
                String::from("Hello World")
            }
        }
    }
}
 
#[test]
fn macro_code_coverage() {
    let file = std::fs::File::open("tests/tests.rs");
    emulate_derive_expansion_fallible(file, "Hello", hello_internal);
}