in shed/quickcheck_arbitrary_derive/src/lib.rs [68:117]
fn derive_arbitrary(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
let DeriveInput {
ident,
generics,
data,
..
} = match syn::parse2(input) {
Ok(input) => input,
Err(err) => return err.to_compile_error(),
};
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
let implem = match data {
syn::Data::Struct(data) => {
let fields = generate_arbitrary_fields(data.fields);
quote::quote! { Self #fields }
}
syn::Data::Enum(data) => {
if data.variants.is_empty() {
return syn::Error::new(ident.span(), EMPTY_ENUMS_DISALLOWED).into_compile_error();
}
let arbitraries = data.variants.into_iter().map(|variant| {
let variant_ident = variant.ident;
let variant_fields = generate_arbitrary_fields(variant.fields);
quote::quote! { Self :: #variant_ident #variant_fields }
});
let variant_indices = (0..arbitraries.len()).map(syn::Index::from);
let num_variants = syn::Index::from(arbitraries.len());
quote::quote! {
match g.choose((0..#num_variants).collect::<Vec<_>>().as_slice()) {
#(Some(&#variant_indices) => #arbitraries,)*
_ => unreachable!("You encountered a bug within the `quickcheck_arbitrary_derive` crate. Please report it back to the maintainers. Thank you! :)"),
}
}
}
syn::Data::Union(_) => {
return syn::Error::new(ident.span(), UNTAGGED_UNIONS_DISALLOWED).into_compile_error();
}
};
quote::quote! {
impl #impl_generics quickcheck::Arbitrary for #ident #ty_generics #where_clause {
fn arbitrary(g: &mut quickcheck::Gen) -> Self {
#implem
}
}
}
}