fn to_tokens()

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(())
                }
            }
        });
    }