Skip to main content

generate_random_macro/
lib.rs

1//! This crate provide the [`GenerateRandom`] derive macro
2//! that implements the trait of the same name from the `generate-random` crate.
3//! Refer to the documentation of that crate for more information.
4
5use syn::{Data, DeriveInput, Fields};
6
7mod handle_enum;
8mod handle_struct;
9
10#[proc_macro_derive(GenerateRandom, attributes(weight))]
11pub fn derive_generate_random(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
12    let input: DeriveInput = syn::parse(input).unwrap();
13    match input.data {
14        Data::Struct(ty) => handle_struct::generate(&input.ident, ty),
15        Data::Enum(ty) => handle_enum::generate(&input.ident, ty),
16        Data::Union(_) => panic!("Unions are not supported"),
17    }
18    .into()
19}
20
21fn generate_fields(fields: Fields) -> proc_macro2::TokenStream {
22    use quote::quote;
23    match fields {
24        Fields::Named(fields) => {
25            let fields = fields
26                .named
27                .into_iter()
28                .map(|field| {
29                    let field = field.ident.unwrap();
30                    quote! {
31                        #field: ::generate_random::GenerateRandom::generate_random(rng),
32                    }
33                })
34                .collect::<proc_macro2::TokenStream>();
35            quote! { { #fields } }
36        }
37        Fields::Unnamed(fields) => {
38            let fields = fields
39                .unnamed
40                .into_iter()
41                .map(|_field| {
42                    quote! {
43                        ::generate_random::GenerateRandom::generate_random(rng),
44                    }
45                })
46                .collect::<proc_macro2::TokenStream>();
47            quote! { ( #fields ) }
48        }
49        Fields::Unit => quote! {},
50    }
51}