difftreelog
misc: rename topic -> Topic
in: master
2 files changed
crates/evm-coder/procedural/src/to_log.rsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617use inflector::cases;18use syn::{Data, DeriveInput, Field, Fields, Ident, Variant, spanned::Spanned};19use quote::quote;2021use crate::{parse_ident_from_path, parse_ident_from_type, snake_ident_to_screaming};2223struct EventField {24 name: Ident,25 camel_name: String,26 ty: Ident,27 indexed: bool,28}2930impl EventField {31 fn try_from(field: &Field) -> syn::Result<Self> {32 let name = field.ident.as_ref().unwrap();33 let ty = parse_ident_from_type(&field.ty, false)?;34 let mut indexed = false;35 for attr in &field.attrs {36 if let Ok(ident) = parse_ident_from_path(&attr.path, false) {37 if ident == "indexed" {38 indexed = true;39 }40 }41 }42 Ok(Self {43 name: name.to_owned(),44 camel_name: cases::camelcase::to_camel_case(&name.to_string()),45 ty: ty.to_owned(),46 indexed,47 })48 }49 fn expand_solidity_argument(&self) -> proc_macro2::TokenStream {50 let camel_name = &self.camel_name;51 let ty = &self.ty;52 let indexed = self.indexed;53 quote! {54 <SolidityEventArgument<#ty>>::new(#indexed, #camel_name)55 }56 }57}5859struct Event {60 name: Ident,61 name_screaming: Ident,62 fields: Vec<EventField>,63 selector: proc_macro2::TokenStream,64}6566impl Event {67 fn try_from(variant: &Variant) -> syn::Result<Self> {68 let name = &variant.ident;69 let name_lit = proc_macro2::Literal::string(name.to_string().as_str());70 let name_screaming = snake_ident_to_screaming(name);7172 let named = match &variant.fields {73 Fields::Named(named) => named,74 _ => {75 return Err(syn::Error::new(76 variant.fields.span(),77 "expected named fields",78 ))79 }80 };81 let mut fields = Vec::new();82 for field in &named.named {83 fields.push(EventField::try_from(field)?);84 }85 if fields.iter().filter(|f| f.indexed).count() > 3 {86 return Err(syn::Error::new(87 variant.fields.span(),88 "events can have at most 4 indexed fields (1 indexed field is reserved for event signature)"89 ));90 }9192 let args = fields.iter().map(|f| {93 let ty = &f.ty;94 quote! {nameof(<#ty as ::evm_coder::abi::AbiType>::SIGNATURE) fixed(",")}95 });96 // Remove trailing comma97 let shift = (!fields.is_empty()).then(|| quote! {shift_left(1)});9899 let signature = quote! { ::evm_coder::make_signature!(new fixed(#name_lit) fixed("(") #(#args)* #shift fixed(")")) };100 let selector = quote! {101 {102 let signature = #signature;103 let mut sum = ::evm_coder::sha3_const::Keccak256::new();104 let mut pos = 0;105 while pos < signature.len {106 sum = sum.update(&[signature.data[pos]; 1]);107 pos += 1;108 }109 let a = sum.finalize();110 let mut selector_bytes = [0; 32];111 let mut i = 0;112 while i != 32 {113 selector_bytes[i] = a[i];114 i += 1;115 }116 selector_bytes117 }118 };119120 Ok(Self {121 name: name.to_owned(),122 name_screaming,123 fields,124 selector,125 })126 }127128 fn expand_serializers(&self) -> proc_macro2::TokenStream {129 let name = &self.name;130 let name_screaming = &self.name_screaming;131 let fields = self.fields.iter().map(|f| &f.name);132133 let indexed = self.fields.iter().filter(|f| f.indexed).map(|f| &f.name);134 let plain = self.fields.iter().filter(|f| !f.indexed).map(|f| &f.name);135136 quote! {137 Self::#name {#(138 #fields,139 )*} => {140 topics.push(topic::from(Self::#name_screaming));141 #(142 topics.push(#indexed.to_topic());143 )*144 #(145 #plain.abi_write(&mut writer);146 )*147 }148 }149 }150151 fn expand_consts(&self) -> proc_macro2::TokenStream {152 let name_screaming = &self.name_screaming;153 let selector = &self.selector;154155 quote! {156 const #name_screaming: [u8; 32] = #selector;157 }158 }159160 fn expand_solidity_function(&self) -> proc_macro2::TokenStream {161 let name = self.name.to_string();162 let args = self.fields.iter().map(EventField::expand_solidity_argument);163 quote! {164 SolidityEvent {165 name: #name,166 args: (167 #(168 #args,169 )*170 ),171 }172 }173 }174}175176pub struct Events {177 name: Ident,178 events: Vec<Event>,179}180181impl Events {182 pub fn try_from(data: &DeriveInput) -> syn::Result<Self> {183 let name = &data.ident;184 let en = match &data.data {185 Data::Enum(en) => en,186 _ => return Err(syn::Error::new(data.span(), "expected enum")),187 };188 let mut events = Vec::new();189 for variant in &en.variants {190 events.push(Event::try_from(variant)?);191 }192 Ok(Self {193 name: name.to_owned(),194 events,195 })196 }197 pub fn expand(&self) -> proc_macro2::TokenStream {198 let name = &self.name;199200 let consts = self.events.iter().map(Event::expand_consts);201 let serializers = self.events.iter().map(Event::expand_serializers);202 let solidity_name = self.name.to_string();203 let solidity_functions = self.events.iter().map(Event::expand_solidity_function);204205 quote! {206 impl #name {207 #(208 #consts209 )*210211 /// Generate solidity definitions for methods described in this interface212 #[cfg(feature = "stubgen")]213 pub fn generate_solidity_interface(tc: &evm_coder::solidity::TypeCollector, is_impl: bool) {214 use evm_coder::solidity::*;215 use core::fmt::Write;216 let interface = SolidityInterface {217 docs: &[],218 selector: [0; 4],219 name: #solidity_name,220 is: &[],221 functions: (#(222 #solidity_functions,223 )*),224 };225 let mut out = string::new();226 out.push_str("/// @dev inlined interface\n");227 let _ = interface.format(is_impl, &mut out, tc);228 tc.collect(out);229 }230 }231232 #[automatically_derived]233 impl ::evm_coder::events::ToLog for #name {234 fn to_log(&self, contract: Address) -> ::ethereum::Log {235 use ::evm_coder::events::ToTopic;236 use ::evm_coder::abi::AbiWrite;237 let mut writer = ::evm_coder::abi::AbiWriter::new();238 let mut topics = Vec::new();239 match self {240 #(241 #serializers,242 )*243 }244 ::ethereum::Log {245 address: contract,246 topics,247 data: writer.finish(),248 }249 }250 }251 }252 }253}1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617use inflector::cases;18use syn::{Data, DeriveInput, Field, Fields, Ident, Variant, spanned::Spanned};19use quote::quote;2021use crate::{parse_ident_from_path, parse_ident_from_type, snake_ident_to_screaming};2223struct EventField {24 name: Ident,25 camel_name: String,26 ty: Ident,27 indexed: bool,28}2930impl EventField {31 fn try_from(field: &Field) -> syn::Result<Self> {32 let name = field.ident.as_ref().unwrap();33 let ty = parse_ident_from_type(&field.ty, false)?;34 let mut indexed = false;35 for attr in &field.attrs {36 if let Ok(ident) = parse_ident_from_path(&attr.path, false) {37 if ident == "indexed" {38 indexed = true;39 }40 }41 }42 Ok(Self {43 name: name.to_owned(),44 camel_name: cases::camelcase::to_camel_case(&name.to_string()),45 ty: ty.to_owned(),46 indexed,47 })48 }49 fn expand_solidity_argument(&self) -> proc_macro2::TokenStream {50 let camel_name = &self.camel_name;51 let ty = &self.ty;52 let indexed = self.indexed;53 quote! {54 <SolidityEventArgument<#ty>>::new(#indexed, #camel_name)55 }56 }57}5859struct Event {60 name: Ident,61 name_screaming: Ident,62 fields: Vec<EventField>,63 selector: proc_macro2::TokenStream,64}6566impl Event {67 fn try_from(variant: &Variant) -> syn::Result<Self> {68 let name = &variant.ident;69 let name_lit = proc_macro2::Literal::string(name.to_string().as_str());70 let name_screaming = snake_ident_to_screaming(name);7172 let named = match &variant.fields {73 Fields::Named(named) => named,74 _ => {75 return Err(syn::Error::new(76 variant.fields.span(),77 "expected named fields",78 ))79 }80 };81 let mut fields = Vec::new();82 for field in &named.named {83 fields.push(EventField::try_from(field)?);84 }85 if fields.iter().filter(|f| f.indexed).count() > 3 {86 return Err(syn::Error::new(87 variant.fields.span(),88 "events can have at most 4 indexed fields (1 indexed field is reserved for event signature)"89 ));90 }9192 let args = fields.iter().map(|f| {93 let ty = &f.ty;94 quote! {nameof(<#ty as ::evm_coder::abi::AbiType>::SIGNATURE) fixed(",")}95 });96 // Remove trailing comma97 let shift = (!fields.is_empty()).then(|| quote! {shift_left(1)});9899 let signature = quote! { ::evm_coder::make_signature!(new fixed(#name_lit) fixed("(") #(#args)* #shift fixed(")")) };100 let selector = quote! {101 {102 let signature = #signature;103 let mut sum = ::evm_coder::sha3_const::Keccak256::new();104 let mut pos = 0;105 while pos < signature.len {106 sum = sum.update(&[signature.data[pos]; 1]);107 pos += 1;108 }109 let a = sum.finalize();110 let mut selector_bytes = [0; 32];111 let mut i = 0;112 while i != 32 {113 selector_bytes[i] = a[i];114 i += 1;115 }116 selector_bytes117 }118 };119120 Ok(Self {121 name: name.to_owned(),122 name_screaming,123 fields,124 selector,125 })126 }127128 fn expand_serializers(&self) -> proc_macro2::TokenStream {129 let name = &self.name;130 let name_screaming = &self.name_screaming;131 let fields = self.fields.iter().map(|f| &f.name);132133 let indexed = self.fields.iter().filter(|f| f.indexed).map(|f| &f.name);134 let plain = self.fields.iter().filter(|f| !f.indexed).map(|f| &f.name);135136 quote! {137 Self::#name {#(138 #fields,139 )*} => {140 topics.push(::evm_coder::types::Topic::from(Self::#name_screaming));141 #(142 topics.push(#indexed.to_topic());143 )*144 #(145 #plain.abi_write(&mut writer);146 )*147 }148 }149 }150151 fn expand_consts(&self) -> proc_macro2::TokenStream {152 let name_screaming = &self.name_screaming;153 let selector = &self.selector;154155 quote! {156 const #name_screaming: [u8; 32] = #selector;157 }158 }159160 fn expand_solidity_function(&self) -> proc_macro2::TokenStream {161 let name = self.name.to_string();162 let args = self.fields.iter().map(EventField::expand_solidity_argument);163 quote! {164 SolidityEvent {165 name: #name,166 args: (167 #(168 #args,169 )*170 ),171 }172 }173 }174}175176pub struct Events {177 name: Ident,178 events: Vec<Event>,179}180181impl Events {182 pub fn try_from(data: &DeriveInput) -> syn::Result<Self> {183 let name = &data.ident;184 let en = match &data.data {185 Data::Enum(en) => en,186 _ => return Err(syn::Error::new(data.span(), "expected enum")),187 };188 let mut events = Vec::new();189 for variant in &en.variants {190 events.push(Event::try_from(variant)?);191 }192 Ok(Self {193 name: name.to_owned(),194 events,195 })196 }197 pub fn expand(&self) -> proc_macro2::TokenStream {198 let name = &self.name;199200 let consts = self.events.iter().map(Event::expand_consts);201 let serializers = self.events.iter().map(Event::expand_serializers);202 let solidity_name = self.name.to_string();203 let solidity_functions = self.events.iter().map(Event::expand_solidity_function);204205 quote! {206 impl #name {207 #(208 #consts209 )*210211 /// Generate solidity definitions for methods described in this interface212 #[cfg(feature = "stubgen")]213 pub fn generate_solidity_interface(tc: &evm_coder::solidity::TypeCollector, is_impl: bool) {214 use evm_coder::solidity::*;215 use core::fmt::Write;216 let interface = SolidityInterface {217 docs: &[],218 selector: [0; 4],219 name: #solidity_name,220 is: &[],221 functions: (#(222 #solidity_functions,223 )*),224 };225 let mut out = string::new();226 out.push_str("/// @dev inlined interface\n");227 let _ = interface.format(is_impl, &mut out, tc);228 tc.collect(out);229 }230 }231232 #[automatically_derived]233 impl ::evm_coder::events::ToLog for #name {234 fn to_log(&self, contract: Address) -> ::ethereum::Log {235 use ::evm_coder::events::ToTopic;236 use ::evm_coder::abi::AbiWrite;237 let mut writer = ::evm_coder::abi::AbiWriter::new();238 let mut topics = Vec::new();239 match self {240 #(241 #serializers,242 )*243 }244 ::ethereum::Log {245 address: contract,246 topics,247 data: writer.finish(),248 }249 }250 }251 }252 }253}crates/evm-coder/src/lib.rsdiffbeforeafterboth--- a/crates/evm-coder/src/lib.rs
+++ b/crates/evm-coder/src/lib.rs
@@ -133,7 +133,7 @@
pub type Address = H160;
pub type Bytes4 = [u8; 4];
- pub type topic = H256;
+ pub type Topic = H256;
#[cfg(not(feature = "std"))]
pub type string = ::alloc::string::String;