difftreelog
feat Calculate event selector at compile time
in: master
1 file changed
crates/evm-coder/procedural/src/to_log.rsdiffbeforeafterboth161617use inflector::cases;17use inflector::cases;18use syn::{Data, DeriveInput, Field, Fields, Ident, Variant, spanned::Spanned};18use syn::{Data, DeriveInput, Field, Fields, Ident, Variant, spanned::Spanned};19use std::fmt::Write;20use quote::quote;19use quote::quote;212022use crate::{parse_ident_from_path, parse_ident_from_type, snake_ident_to_screaming};21use crate::{parse_ident_from_path, parse_ident_from_type, snake_ident_to_screaming};61 name: Ident,60 name: Ident,62 name_screaming: Ident,61 name_screaming: Ident,63 fields: Vec<EventField>,62 fields: Vec<EventField>,64 selector: [u8; 32],63 selector: proc_macro2::TokenStream,65 selector_str: String,66}64}676568impl Event {66impl Event {69 fn try_from(variant: &Variant) -> syn::Result<Self> {67 fn try_from(variant: &Variant) -> syn::Result<Self> {70 let name = &variant.ident;68 let name = &variant.ident;69 let name_lit = proc_macro2::Literal::string(name.to_string().as_str());71 let name_screaming = snake_ident_to_screaming(name);70 let name_screaming = snake_ident_to_screaming(name);727173 let named = match &variant.fields {72 let named = match &variant.fields {90 ));89 ));91 }90 }9192 let mut selector_str = format!("{}(", name);92 let mut args = proc_macro2::TokenStream::new();93 let mut has_params = false;93 for (i, arg) in fields.iter().enumerate() {94 for arg in fields.iter() {94 if i != 0 {95 has_params = true;95 write!(selector_str, ",").unwrap();96 let ty = &arg.ty;96 }97 write!(selector_str, "{}", arg.ty).unwrap();97 args.extend(quote! {nameof(<#ty>::SIGNATURE)});98 args.extend(quote! {fixed(",")})98 }99 }100101 // Remove trailing comma102 if has_params {99 selector_str.push(')');103 args.extend(quote! {shift_left(1)})104 }105106 let signature = quote! { ::evm_coder::make_signature!(new fixed(#name_lit) fixed("(") #args fixed(")")) };107100 let selector = crate::event_selector_str(&selector_str);108 let selector = quote! {109 {110 let signature = #signature;111 let mut sum = ::evm_coder::sha3_const::Keccak256::new();112 let mut pos = 0;113 while pos < signature.len {114 sum = sum.update(&[signature.data[pos]; 1]);115 pos += 1;116 }117 let a = sum.finalize();118 let mut selector_bytes = [0; 32];119 let mut i = 0;120 while i != 32 {121 selector_bytes[i] = a[i];122 i += 1;123 }124 selector_bytes125 }126 };101127102 Ok(Self {128 Ok(Self {103 name: name.to_owned(),129 name: name.to_owned(),104 name_screaming,130 name_screaming,105 fields,131 fields,106 selector,132 selector,107 selector_str,108 })133 })109 }134 }110135133158134 fn expand_consts(&self) -> proc_macro2::TokenStream {159 fn expand_consts(&self) -> proc_macro2::TokenStream {135 let name_screaming = &self.name_screaming;160 let name_screaming = &self.name_screaming;136 let selector_str = &self.selector_str;137 let selector = &self.selector;161 let selector = &self.selector;138162139 quote! {163 quote! {140 #[doc = #selector_str]141 const #name_screaming: [u8; 32] = [#(164 const #name_screaming: [u8; 32] = #selector;142 #selector,143 )*];144 }165 }145 }166 }146167