use quote::quote;
use std::str::FromStr;
use syn::Fields;
pub struct HashableStruct(syn::ItemStruct);
impl HashableStruct {
pub fn new(input: syn::ItemStruct) -> Self {
Self(input)
}
}
impl HashableStruct {
pub fn render(self) -> proc_macro::TokenStream {
let mut strct = self.0;
let struct_name = &strct.ident;
let mut struct_fn_to_node_stream: proc_macro2::TokenStream =
proc_macro2::TokenStream::new();
let mut struct_fn_to_node = vec![format!("keccak::hashv(&[")];
if let Fields::Named(fields) = &mut strct.fields {
fields.named.iter_mut().for_each(|f| {
let field_ident = f.ident.as_ref().unwrap().to_string();
struct_fn_to_node.push(format!("self.{}.to_node().as_ref(),", field_ident));
});
} else if let Fields::Unnamed(fields) = &mut strct.fields {
fields.unnamed.iter_mut().enumerate().for_each(|(i, _)| {
struct_fn_to_node.push(format!("self.{}.to_node().as_ref(),", i));
});
}
struct_fn_to_node.push(format!("]).to_bytes()"));
struct_fn_to_node_stream.extend::<proc_macro2::TokenStream>(
proc_macro2::TokenStream::from_str(&struct_fn_to_node.join("")).unwrap(),
);
let stream: proc_macro2::TokenStream = quote! {
impl ToNode for #struct_name {
fn to_node(&self) -> [u8; 32] {
#struct_fn_to_node_stream
}
}
};
stream.into()
}
}