in propfuzz-macro/src/propfuzz_impl.rs [98:161]
fn to_tokens(&self, tokens: &mut TokenStream) {
let Self {
name,
description,
other_attrs,
config,
struct_name,
body,
..
} = self;
// The ToTokens impl for Option isn't quite what we want, so do this by hand.
let description = match description {
Some(s) => quote! { Some(#s) },
None => quote! { None },
};
let proptest_config = &config.proptest;
let types = body.types();
let name_pats = body.name_pats();
// Use indexes as tuple accessors in fmt_value.
// Note that we can't destructure values because name_pats may contain modifiers like mut.
// TODO: modifiers like mut can be filtered out -- consider doing so for a nicer display.
let indexes = (0..body.num_params()).map(Index::from);
tokens.extend(quote! {
#[test]
#(#other_attrs )*
fn #name() {
::propfuzz::runtime::execute_as_proptest(#struct_name);
}
#[derive(Copy, Clone, Debug)]
#[allow(non_camel_case_types)]
struct #struct_name;
impl ::propfuzz::traits::StructuredTarget for #struct_name {
type Value = (#(#types,)*);
fn name(&self) -> &'static str {
concat!(module_path!(), "::", stringify!(#name))
}
fn description(&self) -> Option<&'static str> {
#description
}
fn proptest_config(&self) -> ::propfuzz::proptest::test_runner::Config {
#proptest_config
}
fn execute(&self, __propfuzz_test_runner: &mut ::propfuzz::proptest::test_runner::TestRunner)
-> ::std::result::Result<(), ::propfuzz::proptest::test_runner::TestError<Self::Value>> {
#body
}
fn fmt_value(&self, value: &Self::Value, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
#(writeln!(f, "{} = {:?}", stringify!(#name_pats), value.#indexes)?;)*
Ok(())
}
}
});
}