mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-03 00:31:50 +00:00
Directory Restructure (#1163)
* Move tests -> testing * Directory restructure * Update Cargo.toml during restructure * Update Makefile during restructure * Fix arbitrary path
This commit is contained in:
13
common/test_random_derive/Cargo.toml
Normal file
13
common/test_random_derive/Cargo.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "test_random_derive"
|
||||
version = "0.2.0"
|
||||
authors = ["thojest <thojest@gmail.com>"]
|
||||
edition = "2018"
|
||||
description = "Procedural derive macros for implementation of TestRandom trait"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
syn = "1.0.18"
|
||||
quote = "1.0.4"
|
||||
61
common/test_random_derive/src/lib.rs
Normal file
61
common/test_random_derive/src/lib.rs
Normal file
@@ -0,0 +1,61 @@
|
||||
extern crate proc_macro;
|
||||
|
||||
use crate::proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{parse_macro_input, DeriveInput};
|
||||
|
||||
/// Returns true if some field has an attribute declaring it should be generated from default (not
|
||||
/// randomized).
|
||||
///
|
||||
/// The field attribute is: `#[test_random(default)]`
|
||||
fn should_use_default(field: &syn::Field) -> bool {
|
||||
field.attrs.iter().any(|attr| {
|
||||
attr.path.is_ident("test_random") && attr.tokens.to_string().replace(" ", "") == "(default)"
|
||||
})
|
||||
}
|
||||
|
||||
#[proc_macro_derive(TestRandom, attributes(test_random))]
|
||||
pub fn test_random_derive(input: TokenStream) -> TokenStream {
|
||||
let derived_input = parse_macro_input!(input as DeriveInput);
|
||||
let name = &derived_input.ident;
|
||||
let (impl_generics, ty_generics, where_clause) = &derived_input.generics.split_for_impl();
|
||||
|
||||
let struct_data = match &derived_input.data {
|
||||
syn::Data::Struct(s) => s,
|
||||
_ => panic!("test_random_derive only supports structs."),
|
||||
};
|
||||
|
||||
// Build quotes for fields that should be generated and those that should be built from
|
||||
// `Default`.
|
||||
let mut quotes = vec![];
|
||||
for field in &struct_data.fields {
|
||||
match &field.ident {
|
||||
Some(ref ident) => {
|
||||
if should_use_default(field) {
|
||||
quotes.push(quote! {
|
||||
#ident: <_>::default(),
|
||||
});
|
||||
} else {
|
||||
quotes.push(quote! {
|
||||
#ident: <_>::random_for_test(rng),
|
||||
});
|
||||
}
|
||||
}
|
||||
_ => panic!("test_random_derive only supports named struct fields."),
|
||||
};
|
||||
}
|
||||
|
||||
let output = quote! {
|
||||
impl #impl_generics TestRandom for #name #ty_generics #where_clause {
|
||||
fn random_for_test(rng: &mut impl rand::RngCore) -> Self {
|
||||
Self {
|
||||
#(
|
||||
#quotes
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
output.into()
|
||||
}
|
||||
Reference in New Issue
Block a user