replaced manual TestRandom implementation with macro when possible; fixed typo in TestRandom macro (lighthouse-246)

This commit is contained in:
thojest 2019-02-22 17:10:26 +01:00
parent 278b41c8ef
commit 66b5accdc2
24 changed files with 51 additions and 284 deletions

View File

@ -20,6 +20,7 @@ slog = "^2.2.3"
ssz = { path = "../utils/ssz" }
ssz_derive = { path = "../utils/ssz_derive" }
swap_or_not_shuffle = { path = "../utils/swap_or_not_shuffle" }
test_random_derive = { path = "../utils/test_random_derive" }
[dev-dependencies]
env_logger = "0.6.0"

View File

@ -4,8 +4,9 @@ use rand::RngCore;
use serde_derive::Serialize;
use ssz::{hash, TreeHash};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
#[derive(Debug, Clone, PartialEq, Serialize, Encode, Decode)]
#[derive(Debug, Clone, PartialEq, Serialize, Encode, Decode, TestRandom)]
pub struct Attestation {
pub aggregation_bitfield: Bitfield,
pub data: AttestationData,
@ -45,17 +46,6 @@ impl TreeHash for Attestation {
}
}
impl<T: RngCore> TestRandom<T> for Attestation {
fn random_for_test(rng: &mut T) -> Self {
Self {
data: <_>::random_for_test(rng),
aggregation_bitfield: <_>::random_for_test(rng),
custody_bitfield: <_>::random_for_test(rng),
aggregate_signature: <_>::random_for_test(rng),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -4,6 +4,7 @@ use rand::RngCore;
use serde_derive::Serialize;
use ssz::{hash, TreeHash};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
pub const SSZ_ATTESTION_DATA_LENGTH: usize = {
8 + // slot
@ -16,7 +17,7 @@ pub const SSZ_ATTESTION_DATA_LENGTH: usize = {
32 // justified_block_root
};
#[derive(Debug, Clone, PartialEq, Default, Serialize, Hash, Encode, Decode)]
#[derive(Debug, Clone, PartialEq, Default, Serialize, Hash, Encode, Decode, TestRandom)]
pub struct AttestationData {
pub slot: Slot,
pub shard: u64,
@ -59,21 +60,6 @@ impl TreeHash for AttestationData {
}
}
impl<T: RngCore> TestRandom<T> for AttestationData {
fn random_for_test(rng: &mut T) -> Self {
Self {
slot: <_>::random_for_test(rng),
shard: <_>::random_for_test(rng),
beacon_block_root: <_>::random_for_test(rng),
epoch_boundary_root: <_>::random_for_test(rng),
shard_block_root: <_>::random_for_test(rng),
latest_crosslink: <_>::random_for_test(rng),
justified_epoch: <_>::random_for_test(rng),
justified_block_root: <_>::random_for_test(rng),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -3,8 +3,9 @@ use rand::RngCore;
use serde_derive::Serialize;
use ssz::{hash, TreeHash};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode)]
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode, TestRandom)]
pub struct AttesterSlashing {
pub slashable_attestation_1: SlashableAttestation,
pub slashable_attestation_2: SlashableAttestation,
@ -19,15 +20,6 @@ impl TreeHash for AttesterSlashing {
}
}
impl<T: RngCore> TestRandom<T> for AttesterSlashing {
fn random_for_test(rng: &mut T) -> Self {
Self {
slashable_attestation_1: <_>::random_for_test(rng),
slashable_attestation_2: <_>::random_for_test(rng),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -5,8 +5,9 @@ use rand::RngCore;
use serde_derive::Serialize;
use ssz::{hash, TreeHash};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode)]
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode, TestRandom)]
pub struct BeaconBlock {
pub slot: Slot,
pub parent_root: Hash256,
@ -74,20 +75,6 @@ impl TreeHash for BeaconBlock {
}
}
impl<T: RngCore> TestRandom<T> for BeaconBlock {
fn random_for_test(rng: &mut T) -> Self {
Self {
slot: <_>::random_for_test(rng),
parent_root: <_>::random_for_test(rng),
state_root: <_>::random_for_test(rng),
randao_reveal: <_>::random_for_test(rng),
eth1_data: <_>::random_for_test(rng),
signature: <_>::random_for_test(rng),
body: <_>::random_for_test(rng),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -4,8 +4,9 @@ use rand::RngCore;
use serde_derive::Serialize;
use ssz::{hash, TreeHash};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
#[derive(Debug, PartialEq, Clone, Default, Serialize, Encode, Decode)]
#[derive(Debug, PartialEq, Clone, Default, Serialize, Encode, Decode, TestRandom)]
pub struct BeaconBlockBody {
pub proposer_slashings: Vec<ProposerSlashing>,
pub attester_slashings: Vec<AttesterSlashing>,
@ -26,18 +27,6 @@ impl TreeHash for BeaconBlockBody {
}
}
impl<T: RngCore> TestRandom<T> for BeaconBlockBody {
fn random_for_test(rng: &mut T) -> Self {
Self {
proposer_slashings: <_>::random_for_test(rng),
attester_slashings: <_>::random_for_test(rng),
attestations: <_>::random_for_test(rng),
deposits: <_>::random_for_test(rng),
exits: <_>::random_for_test(rng),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -12,6 +12,7 @@ use serde_derive::Serialize;
use ssz::{hash, TreeHash};
use ssz_derive::{Decode, Encode};
use swap_or_not_shuffle::get_permutated_index;
use test_random_derive::TestRandom;
mod tests;
@ -52,7 +53,7 @@ macro_rules! safe_sub_assign {
};
}
#[derive(Debug, PartialEq, Clone, Default, Serialize, Encode, Decode)]
#[derive(Debug, PartialEq, Clone, Default, Serialize, Encode, Decode, TestRandom)]
pub struct BeaconState {
// Misc
pub slot: Slot,
@ -1003,35 +1004,3 @@ impl TreeHash for BeaconState {
hash(&result)
}
}
impl<T: RngCore> TestRandom<T> for BeaconState {
fn random_for_test(rng: &mut T) -> Self {
Self {
slot: <_>::random_for_test(rng),
genesis_time: <_>::random_for_test(rng),
fork: <_>::random_for_test(rng),
validator_registry: <_>::random_for_test(rng),
validator_balances: <_>::random_for_test(rng),
validator_registry_update_epoch: <_>::random_for_test(rng),
latest_randao_mixes: <_>::random_for_test(rng),
previous_epoch_start_shard: <_>::random_for_test(rng),
current_epoch_start_shard: <_>::random_for_test(rng),
previous_calculation_epoch: <_>::random_for_test(rng),
current_calculation_epoch: <_>::random_for_test(rng),
previous_epoch_seed: <_>::random_for_test(rng),
current_epoch_seed: <_>::random_for_test(rng),
previous_justified_epoch: <_>::random_for_test(rng),
justified_epoch: <_>::random_for_test(rng),
justification_bitfield: <_>::random_for_test(rng),
finalized_epoch: <_>::random_for_test(rng),
latest_crosslinks: <_>::random_for_test(rng),
latest_block_roots: <_>::random_for_test(rng),
latest_index_roots: <_>::random_for_test(rng),
latest_penalized_balances: <_>::random_for_test(rng),
latest_attestations: <_>::random_for_test(rng),
batched_block_roots: <_>::random_for_test(rng),
latest_eth1_data: <_>::random_for_test(rng),
eth1_data_votes: <_>::random_for_test(rng),
}
}
}

View File

@ -4,8 +4,9 @@ use rand::RngCore;
use serde_derive::Serialize;
use ssz::{hash, TreeHash};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode)]
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode, TestRandom)]
pub struct CasperSlashing {
pub slashable_vote_data_1: SlashableVoteData,
pub slashable_vote_data_2: SlashableVoteData,
@ -20,15 +21,6 @@ impl TreeHash for CasperSlashing {
}
}
impl<T: RngCore> TestRandom<T> for CasperSlashing {
fn random_for_test(rng: &mut T) -> Self {
Self {
slashable_vote_data_1: <_>::random_for_test(rng),
slashable_vote_data_2: <_>::random_for_test(rng),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -4,8 +4,9 @@ use rand::RngCore;
use serde_derive::Serialize;
use ssz::{hash, TreeHash};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
#[derive(Debug, Clone, PartialEq, Default, Serialize, Hash, Encode, Decode)]
#[derive(Debug, Clone, PartialEq, Default, Serialize, Hash, Encode, Decode, TestRandom)]
pub struct Crosslink {
pub epoch: Epoch,
pub shard_block_root: Hash256,
@ -30,15 +31,6 @@ impl TreeHash for Crosslink {
}
}
impl<T: RngCore> TestRandom<T> for Crosslink {
fn random_for_test(rng: &mut T) -> Self {
Self {
epoch: <_>::random_for_test(rng),
shard_block_root: <_>::random_for_test(rng),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -4,8 +4,9 @@ use rand::RngCore;
use serde_derive::Serialize;
use ssz::{hash, TreeHash};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode)]
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode, TestRandom)]
pub struct Deposit {
pub branch: Vec<Hash256>,
pub index: u64,
@ -22,16 +23,6 @@ impl TreeHash for Deposit {
}
}
impl<T: RngCore> TestRandom<T> for Deposit {
fn random_for_test(rng: &mut T) -> Self {
Self {
branch: <_>::random_for_test(rng),
index: <_>::random_for_test(rng),
deposit_data: <_>::random_for_test(rng),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -4,8 +4,9 @@ use rand::RngCore;
use serde_derive::Serialize;
use ssz::{hash, TreeHash};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode)]
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode, TestRandom)]
pub struct DepositData {
pub amount: u64,
pub timestamp: u64,
@ -22,16 +23,6 @@ impl TreeHash for DepositData {
}
}
impl<T: RngCore> TestRandom<T> for DepositData {
fn random_for_test(rng: &mut T) -> Self {
Self {
amount: <_>::random_for_test(rng),
timestamp: <_>::random_for_test(rng),
deposit_input: <_>::random_for_test(rng),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -5,8 +5,9 @@ use rand::RngCore;
use serde_derive::Serialize;
use ssz::{hash, TreeHash};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode)]
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode, TestRandom)]
pub struct DepositInput {
pub pubkey: PublicKey,
pub withdrawal_credentials: Hash256,
@ -23,16 +24,6 @@ impl TreeHash for DepositInput {
}
}
impl<T: RngCore> TestRandom<T> for DepositInput {
fn random_for_test(rng: &mut T) -> Self {
Self {
pubkey: <_>::random_for_test(rng),
withdrawal_credentials: <_>::random_for_test(rng),
proof_of_possession: <_>::random_for_test(rng),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -4,9 +4,10 @@ use rand::RngCore;
use serde_derive::Serialize;
use ssz::{hash, TreeHash};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
// Note: this is refer to as DepositRootVote in specs
#[derive(Debug, PartialEq, Clone, Default, Serialize, Encode, Decode)]
#[derive(Debug, PartialEq, Clone, Default, Serialize, Encode, Decode, TestRandom)]
pub struct Eth1Data {
pub deposit_root: Hash256,
pub block_hash: Hash256,
@ -21,15 +22,6 @@ impl TreeHash for Eth1Data {
}
}
impl<T: RngCore> TestRandom<T> for Eth1Data {
fn random_for_test(rng: &mut T) -> Self {
Self {
deposit_root: <_>::random_for_test(rng),
block_hash: <_>::random_for_test(rng),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -4,9 +4,10 @@ use rand::RngCore;
use serde_derive::Serialize;
use ssz::{hash, TreeHash};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
// Note: this is refer to as DepositRootVote in specs
#[derive(Debug, PartialEq, Clone, Default, Serialize, Encode, Decode)]
#[derive(Debug, PartialEq, Clone, Default, Serialize, Encode, Decode, TestRandom)]
pub struct Eth1DataVote {
pub eth1_data: Eth1Data,
pub vote_count: u64,
@ -21,15 +22,6 @@ impl TreeHash for Eth1DataVote {
}
}
impl<T: RngCore> TestRandom<T> for Eth1DataVote {
fn random_for_test(rng: &mut T) -> Self {
Self {
eth1_data: <_>::random_for_test(rng),
vote_count: <_>::random_for_test(rng),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -4,8 +4,9 @@ use rand::RngCore;
use serde_derive::Serialize;
use ssz::{hash, TreeHash};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode)]
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode, TestRandom)]
pub struct Exit {
pub epoch: Epoch,
pub validator_index: u64,
@ -22,16 +23,6 @@ impl TreeHash for Exit {
}
}
impl<T: RngCore> TestRandom<T> for Exit {
fn random_for_test(rng: &mut T) -> Self {
Self {
epoch: <_>::random_for_test(rng),
validator_index: <_>::random_for_test(rng),
signature: <_>::random_for_test(rng),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -3,8 +3,9 @@ use rand::RngCore;
use serde_derive::Serialize;
use ssz::{hash, TreeHash};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
#[derive(Debug, Clone, PartialEq, Default, Serialize, Encode, Decode)]
#[derive(Debug, Clone, PartialEq, Default, Serialize, Encode, Decode, TestRandom)]
pub struct Fork {
pub previous_version: u64,
pub current_version: u64,
@ -21,16 +22,6 @@ impl TreeHash for Fork {
}
}
impl<T: RngCore> TestRandom<T> for Fork {
fn random_for_test(rng: &mut T) -> Self {
Self {
previous_version: <_>::random_for_test(rng),
current_version: <_>::random_for_test(rng),
epoch: <_>::random_for_test(rng),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -4,8 +4,9 @@ use rand::RngCore;
use serde_derive::Serialize;
use ssz::{hash, TreeHash};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
#[derive(Debug, Clone, PartialEq, Serialize, Encode, Decode)]
#[derive(Debug, Clone, PartialEq, Serialize, Encode, Decode, TestRandom)]
pub struct PendingAttestation {
pub aggregation_bitfield: Bitfield,
pub data: AttestationData,
@ -24,17 +25,6 @@ impl TreeHash for PendingAttestation {
}
}
impl<T: RngCore> TestRandom<T> for PendingAttestation {
fn random_for_test(rng: &mut T) -> Self {
Self {
data: <_>::random_for_test(rng),
aggregation_bitfield: <_>::random_for_test(rng),
custody_bitfield: <_>::random_for_test(rng),
inclusion_slot: <_>::random_for_test(rng),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -4,8 +4,9 @@ use rand::RngCore;
use serde_derive::Serialize;
use ssz::{hash, TreeHash};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
#[derive(Debug, PartialEq, Clone, Default, Serialize, Encode, Decode)]
#[derive(Debug, PartialEq, Clone, Default, Serialize, Encode, Decode, TestRandom)]
pub struct ProposalSignedData {
pub slot: Slot,
pub shard: u64,
@ -22,16 +23,6 @@ impl TreeHash for ProposalSignedData {
}
}
impl<T: RngCore> TestRandom<T> for ProposalSignedData {
fn random_for_test(rng: &mut T) -> Self {
Self {
slot: <_>::random_for_test(rng),
shard: <_>::random_for_test(rng),
block_root: <_>::random_for_test(rng),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -5,8 +5,9 @@ use rand::RngCore;
use serde_derive::Serialize;
use ssz::{hash, TreeHash};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode)]
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode, TestRandom)]
pub struct ProposerSlashing {
pub proposer_index: u64,
pub proposal_data_1: ProposalSignedData,
@ -27,18 +28,6 @@ impl TreeHash for ProposerSlashing {
}
}
impl<T: RngCore> TestRandom<T> for ProposerSlashing {
fn random_for_test(rng: &mut T) -> Self {
Self {
proposer_index: <_>::random_for_test(rng),
proposal_data_1: <_>::random_for_test(rng),
proposal_signature_1: <_>::random_for_test(rng),
proposal_data_2: <_>::random_for_test(rng),
proposal_signature_2: <_>::random_for_test(rng),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -3,8 +3,9 @@ use rand::RngCore;
use serde_derive::Serialize;
use ssz::{hash, TreeHash};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode)]
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode, TestRandom)]
pub struct ShardReassignmentRecord {
pub validator_index: u64,
pub shard: u64,
@ -21,16 +22,6 @@ impl TreeHash for ShardReassignmentRecord {
}
}
impl<T: RngCore> TestRandom<T> for ShardReassignmentRecord {
fn random_for_test(rng: &mut T) -> Self {
Self {
validator_index: <_>::random_for_test(rng),
shard: <_>::random_for_test(rng),
slot: <_>::random_for_test(rng),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -3,8 +3,9 @@ use rand::RngCore;
use serde_derive::Serialize;
use ssz::{hash, TreeHash};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode)]
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode, TestRandom)]
pub struct SlashableAttestation {
pub validator_indices: Vec<u64>,
pub data: AttestationData,
@ -23,17 +24,6 @@ impl TreeHash for SlashableAttestation {
}
}
impl<T: RngCore> TestRandom<T> for SlashableAttestation {
fn random_for_test(rng: &mut T) -> Self {
Self {
validator_indices: <_>::random_for_test(rng),
data: <_>::random_for_test(rng),
custody_bitfield: <_>::random_for_test(rng),
aggregate_signature: <_>::random_for_test(rng),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -6,8 +6,9 @@ use rand::RngCore;
use serde_derive::Serialize;
use ssz::{hash, TreeHash};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode)]
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode, TestRandom)]
pub struct SlashableVoteData {
pub custody_bit_0_indices: Vec<u32>,
pub custody_bit_1_indices: Vec<u32>,
@ -47,17 +48,6 @@ impl TreeHash for SlashableVoteData {
}
}
impl<T: RngCore> TestRandom<T> for SlashableVoteData {
fn random_for_test(rng: &mut T) -> Self {
Self {
custody_bit_0_indices: <_>::random_for_test(rng),
custody_bit_1_indices: <_>::random_for_test(rng),
data: <_>::random_for_test(rng),
aggregate_signature: <_>::random_for_test(rng),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -4,9 +4,10 @@ use rand::RngCore;
use serde_derive::Serialize;
use ssz::{hash, TreeHash};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
// The information gathered from the PoW chain validator registration function.
#[derive(Debug, Clone, PartialEq, Serialize, Encode, Decode)]
#[derive(Debug, Clone, PartialEq, Serialize, Encode, Decode, TestRandom)]
pub struct ValidatorRegistryDeltaBlock {
pub latest_registry_delta_root: Hash256,
pub validator_index: u32,
@ -40,18 +41,6 @@ impl TreeHash for ValidatorRegistryDeltaBlock {
}
}
impl<T: RngCore> TestRandom<T> for ValidatorRegistryDeltaBlock {
fn random_for_test(rng: &mut T) -> Self {
Self {
latest_registry_delta_root: <_>::random_for_test(rng),
validator_index: <_>::random_for_test(rng),
pubkey: <_>::random_for_test(rng),
slot: <_>::random_for_test(rng),
flag: <_>::random_for_test(rng),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -6,22 +6,22 @@ use syn::{parse_macro_input, DeriveInput};
#[proc_macro_derive(TestRandom)]
pub fn test_random_derive(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput);
let name = &ast.ident;
let derived_input = parse_macro_input!(input as DeriveInput);
let name = &derived_input.ident;
let struct_data = match &ast.data {
let struct_data = match &derived_input.data {
syn::Data::Struct(s) => s,
_ => panic!("test_random_derive only supports structs."),
};
let field_names = get_named_field_idents_and_types(&struct_data);
let field_names = get_named_field_idents(&struct_data);
let output = quote! {
impl<T: RngCore> TestRandom<T> for #name {
fn random_for_test(rng: &mut T) -> Self {
Self {
#(
#field_names: <_>::random_for_test(rng)
#field_names: <_>::random_for_test(rng),
)*
}
}
@ -31,7 +31,7 @@ pub fn test_random_derive(input: TokenStream) -> TokenStream {
output.into()
}
fn get_named_field_idents_and_types(struct_data: &syn::DataStruct) -> Vec<(&syn::Ident)> {
fn get_named_field_idents(struct_data: &syn::DataStruct) -> Vec<(&syn::Ident)> {
struct_data
.fields
.iter()