difftreelog
feat generate solidity and abi traits for enums
in: master
3 files changed
crates/evm-coder/procedural/src/abi_derive.rsdiffbeforeafterboth--- a/crates/evm-coder/procedural/src/abi_derive.rs
+++ b/crates/evm-coder/procedural/src/abi_derive.rs
@@ -44,13 +44,14 @@
let struct_from_tuple = struct_from_tuple(name, is_named_fields, field_names.clone());
let can_be_plcaed_in_vec = impl_can_be_placed_in_vec(name);
- let abi_type = impl_abi_type(name, tuple_type.clone());
- let abi_read = impl_abi_read(name, tuple_type, tuple_names, struct_from_tuple);
- let abi_write = impl_abi_write(name, is_named_fields, tuple_ref_type, tuple_data);
- let solidity_type = impl_solidity_type(name, field_types.clone(), params_count);
- let solidity_type_name = impl_solidity_type_name(name, field_types.clone(), params_count);
+ let abi_type = impl_struct_abi_type(name, tuple_type.clone());
+ let abi_read = impl_struct_abi_read(name, tuple_type, tuple_names, struct_from_tuple);
+ let abi_write = impl_struct_abi_write(name, is_named_fields, tuple_ref_type, tuple_data);
+ let solidity_type = impl_struct_solidity_type(name, field_types.clone(), params_count);
+ let solidity_type_name =
+ impl_struct_solidity_type_name(name, field_types.clone(), params_count);
let solidity_struct_collect =
- impl_solidity_struct_collect(name, field_names, field_types, field_docs, &docs)?;
+ impl_struct_solidity_struct_collect(name, field_names, field_types, field_docs, &docs)?;
Ok(quote! {
#can_be_plcaed_in_vec
@@ -69,14 +70,177 @@
) -> syn::Result<proc_macro2::TokenStream> {
let name = &ast.ident;
check_repr_u8(name, &ast.attrs)?;
- check_option_validity(de)?;
+ let option_count = check_and_count_option(de)?;
+ let enum_options = de.variants.iter().map(|v| &v.ident);
+
+ let from = impl_enum_from_u8(name, enum_options.clone());
+ let solidity_option = impl_solidity_option(name, enum_options.clone());
+ let can_be_plcaed_in_vec = impl_can_be_placed_in_vec(name);
+ let abi_type = impl_enum_abi_type(name);
+ let abi_read = impl_enum_abi_read(name);
+ let abi_write = impl_enum_abi_write(name);
+ let solidity_type_name = impl_enum_solidity_type_name(name, enum_options.clone());
+ let solidity_struct_collect =
+ impl_enum_solidity_struct_collect(name, enum_options, option_count);
+
+ Ok(quote! {
+ #from
+ #solidity_option
+ #can_be_plcaed_in_vec
+ #abi_type
+ #abi_read
+ #abi_write
+ #solidity_type_name
+ #solidity_struct_collect
+ })
+}
+
+fn impl_solidity_option<'a>(
+ name: &proc_macro2::Ident,
+ enum_options: impl Iterator<Item = &'a syn::Ident>,
+) -> proc_macro2::TokenStream {
+ let enum_options = enum_options.map(|opt| {
+ let s = name.to_string() + "." + opt.to_string().as_str();
+ let as_string = proc_macro2::Literal::string(s.as_str());
+ quote!(#name::#opt => #as_string,)
+ });
+ quote!(
+ impl ::evm_coder::solidity::SolidityEnum for #name {
+ fn solidity_option(&self) -> &str {
+ match <#name>::default() {
+ #(#enum_options)*
+ }
+ }
+ }
+ )
+}
+
+fn impl_enum_from_u8<'a>(
+ name: &proc_macro2::Ident,
+ enum_options: impl Iterator<Item = &'a syn::Ident>,
+) -> proc_macro2::TokenStream {
+ let enum_options = enum_options.enumerate().map(|(i, opt)| {
+ let n = proc_macro2::Literal::u8_suffixed(i as u8);
+ quote! {#n => Ok(#name::#opt),}
+ });
+ quote!(
+ impl TryFrom<u8> for #name {
+ type Error = &'static str;
+
+ fn try_from(value: u8) -> ::std::result::Result<Self, Self::Error> {
+ const err: &'static str = "Not convertible";
+ match value {
+ #(#enum_options)*
+ _ => Err(err)
+ }
+ }
+ }
+ )
+}
- dbg!(&de);
+fn impl_enum_abi_type(name: &syn::Ident) -> proc_macro2::TokenStream {
+ quote! {
+ impl ::evm_coder::abi::AbiType for #name {
+ const SIGNATURE: ::evm_coder::custom_signature::SignatureUnit = <u8 as ::evm_coder::abi::AbiType>::SIGNATURE;
- Ok(quote!())
+ fn is_dynamic() -> bool {
+ <u8 as ::evm_coder::abi::AbiType>::is_dynamic()
+ }
+ fn size() -> usize {
+ <u8 as ::evm_coder::abi::AbiType>::size()
+ }
+ }
+ }
}
-fn check_option_validity(de: &syn::DataEnum) -> syn::Result<()> {
+fn impl_enum_abi_read(name: &syn::Ident) -> proc_macro2::TokenStream {
+ quote!(
+ impl ::evm_coder::abi::AbiRead for #name {
+ fn abi_read(reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Self> {
+ Ok(
+ <u8 as ::evm_coder::abi::AbiRead>::abi_read(reader)?
+ .try_into()?
+ )
+ }
+ }
+ )
+}
+
+fn impl_enum_abi_write(name: &syn::Ident) -> proc_macro2::TokenStream {
+ quote!(
+ impl ::evm_coder::abi::AbiWrite for #name {
+ fn abi_write(&self, writer: &mut ::evm_coder::abi::AbiWriter) {
+ ::evm_coder::abi::AbiWrite::abi_write(&(*self as u8), writer);
+ }
+ }
+ )
+}
+
+fn impl_enum_solidity_type_name<'a>(
+ name: &syn::Ident,
+ enum_options: impl Iterator<Item = &'a syn::Ident>,
+) -> proc_macro2::TokenStream {
+ let enum_options = enum_options.map(|opt| quote!(,));
+ quote!(
+ #[cfg(feature = "stubgen")]
+ impl ::evm_coder::solidity::SolidityTypeName for #name {
+ fn solidity_name(
+ writer: &mut impl ::core::fmt::Write,
+ tc: &::evm_coder::solidity::TypeCollector,
+ ) -> ::core::fmt::Result {
+ write!(writer, "{}", tc.collect_struct::<Self>())
+ }
+
+ fn is_simple() -> bool {
+ true
+ }
+
+ fn solidity_default(
+ writer: &mut impl ::core::fmt::Write,
+ tc: &::evm_coder::solidity::TypeCollector,
+ ) -> ::core::fmt::Result {
+ write!(writer, "{}", <#name as ::evm_coder::solidity::SolidityEnum>::solidity_option(&<#name>::default()))
+ }
+ }
+ )
+}
+
+fn impl_enum_solidity_struct_collect<'a>(
+ name: &syn::Ident,
+ enum_options: impl Iterator<Item = &'a syn::Ident>,
+ option_count: usize,
+) -> proc_macro2::TokenStream {
+ let string_name = name.to_string();
+ let enum_options = enum_options.enumerate().map(|(i, opt)| {
+ let opt = proc_macro2::Literal::string(opt.to_string().as_str());
+ let comma = if i != option_count - 1 { "," } else { "" };
+ quote! {
+ writeln!(str, "\t{}{}", #opt, #comma).expect("Enum format option");
+ }
+ });
+ quote!(
+ #[cfg(feature = "stubgen")]
+ impl ::evm_coder::solidity::StructCollect for #name {
+ fn name() -> String {
+ #string_name.into()
+ }
+
+ fn declaration() -> String {
+ use std::fmt::Write;
+
+ let mut str = String::new();
+ // #(#docs)*
+ writeln!(str, "enum {} {{", <Self as ::evm_coder::solidity::StructCollect>::name()).unwrap();
+ #(#enum_options)*
+ writeln!(str, "}}").unwrap();
+ str
+ }
+ }
+ )
+}
+
+fn check_and_count_option(de: &syn::DataEnum) -> syn::Result<usize> {
+ let mut count = 0;
for error in de.variants.iter().filter_map(|v| {
if !v.fields.is_empty() {
Some(Err(syn::Error::new(
@@ -89,13 +253,14 @@
"Enumeration options should not have an explicit specified value",
)))
} else {
+ count += 1;
None
}
}) {
return error;
}
- Ok(())
+ Ok(count)
}
fn check_repr_u8(name: &syn::Ident, attrs: &Vec<syn::Attribute>) -> syn::Result<()> {
@@ -271,7 +436,7 @@
}
}
-fn impl_abi_type(
+fn impl_struct_abi_type(
name: &syn::Ident,
tuple_type: proc_macro2::TokenStream,
) -> proc_macro2::TokenStream {
@@ -288,7 +453,7 @@
}
}
-fn impl_abi_read(
+fn impl_struct_abi_read(
name: &syn::Ident,
tuple_type: proc_macro2::TokenStream,
tuple_names: proc_macro2::TokenStream,
@@ -304,7 +469,7 @@
)
}
-fn impl_abi_write(
+fn impl_struct_abi_write(
name: &syn::Ident,
_is_named_fields: bool,
tuple_type: proc_macro2::TokenStream,
@@ -319,7 +484,7 @@
)
}
-fn impl_solidity_type<'a>(
+fn impl_struct_solidity_type<'a>(
name: &syn::Ident,
field_types: impl Iterator<Item = &'a syn::Type> + Clone,
params_count: usize,
@@ -347,7 +512,7 @@
}
}
-fn impl_solidity_type_name<'a>(
+fn impl_struct_solidity_type_name<'a>(
name: &syn::Ident,
field_types: impl Iterator<Item = &'a syn::Type> + Clone,
params_count: usize,
@@ -390,7 +555,7 @@
}
}
-fn impl_solidity_struct_collect<'a>(
+fn impl_struct_solidity_struct_collect<'a>(
name: &syn::Ident,
field_names: impl Iterator<Item = proc_macro2::Ident> + Clone,
field_types: impl Iterator<Item = &'a syn::Type> + Clone,
crates/evm-coder/src/solidity/traits.rsdiffbeforeafterboth--- a/crates/evm-coder/src/solidity/traits.rs
+++ b/crates/evm-coder/src/solidity/traits.rs
@@ -8,6 +8,10 @@
fn declaration() -> String;
}
+pub trait SolidityEnum: 'static {
+ fn solidity_option(&self) -> &str;
+}
+
pub trait SolidityTypeName: 'static {
fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result;
/// "simple" types are stored inline, no `memory` modifier should be used in solidity
crates/evm-coder/tests/abi_derive_generation.rsdiffbeforeafterboth1mod test_struct {2 use evm_coder_procedural::AbiCoder;3 use evm_coder::types::bytes;45 #[test]6 fn empty_struct() {7 let t = trybuild::TestCases::new();8 t.compile_fail("tests/build_failed/abi_derive_struct_generation.rs");9 }1011 #[derive(AbiCoder, PartialEq, Debug)]12 struct TypeStruct1SimpleParam {13 _a: u8,14 }1516 #[derive(AbiCoder, PartialEq, Debug)]17 struct TypeStruct1DynamicParam {18 _a: String,19 }2021 #[derive(AbiCoder, PartialEq, Debug)]22 struct TypeStruct2SimpleParam {23 _a: u8,24 _b: u32,25 }2627 #[derive(AbiCoder, PartialEq, Debug)]28 struct TypeStruct2DynamicParam {29 _a: String,30 _b: bytes,31 }3233 #[derive(AbiCoder, PartialEq, Debug)]34 struct TypeStruct2MixedParam {35 _a: u8,36 _b: bytes,37 }3839 #[derive(AbiCoder, PartialEq, Debug)]40 struct TypeStruct1DerivedSimpleParam {41 _a: TypeStruct1SimpleParam,42 }4344 #[derive(AbiCoder, PartialEq, Debug)]45 struct TypeStruct2DerivedSimpleParam {46 _a: TypeStruct1SimpleParam,47 _b: TypeStruct2SimpleParam,48 }4950 #[derive(AbiCoder, PartialEq, Debug)]51 struct TypeStruct1DerivedDynamicParam {52 _a: TypeStruct1DynamicParam,53 }5455 #[derive(AbiCoder, PartialEq, Debug)]56 struct TypeStruct2DerivedDynamicParam {57 _a: TypeStruct1DynamicParam,58 _b: TypeStruct2DynamicParam,59 }6061 /// Some docs62 /// At multi63 /// line64 #[derive(AbiCoder, PartialEq, Debug)]65 struct TypeStruct3DerivedMixedParam {66 /// Docs for A67 /// multi68 /// line69 _a: TypeStruct1SimpleParam,70 /// Docs for B71 _b: TypeStruct2DynamicParam,72 /// Docs for C73 _c: TypeStruct2MixedParam,74 }7576 #[test]77 #[cfg(feature = "stubgen")]78 fn struct_collect_TypeStruct3DerivedMixedParam() {79 assert_eq!(80 <TypeStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::name(),81 "TypeStruct3DerivedMixedParam"82 );83 assert_eq!(84 <TypeStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::declaration(),85 r#"/// @dev Some docs86/// At multi87/// line88struct TypeStruct3DerivedMixedParam {89 /// @dev Docs for A90 /// multi91 /// line92 TypeStruct1SimpleParam _a;93 /// @dev Docs for B94 TypeStruct2DynamicParam _b;95 /// @dev Docs for C96 TypeStruct2MixedParam _c;97}98"#99 );100 }101102 #[test]103 fn impl_abi_type_signature() {104 assert_eq!(105 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE106 .as_str()107 .unwrap(),108 "(uint8)"109 );110 assert_eq!(111 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE112 .as_str()113 .unwrap(),114 "(string)"115 );116 assert_eq!(117 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE118 .as_str()119 .unwrap(),120 "(uint8,uint32)"121 );122 assert_eq!(123 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE124 .as_str()125 .unwrap(),126 "(string,bytes)"127 );128 assert_eq!(129 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE130 .as_str()131 .unwrap(),132 "(uint8,bytes)"133 );134 assert_eq!(135 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE136 .as_str()137 .unwrap(),138 "((uint8))"139 );140 assert_eq!(141 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE142 .as_str()143 .unwrap(),144 "((uint8),(uint8,uint32))"145 );146 assert_eq!(147 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE148 .as_str()149 .unwrap(),150 "((string))"151 );152 assert_eq!(153 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE154 .as_str()155 .unwrap(),156 "((string),(string,bytes))"157 );158 assert_eq!(159 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE160 .as_str()161 .unwrap(),162 "((uint8),(string,bytes),(uint8,bytes))"163 );164 }165166 #[test]167 fn impl_abi_type_is_dynamic() {168 assert_eq!(169 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),170 false171 );172 assert_eq!(173 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),174 true175 );176 assert_eq!(177 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),178 false179 );180 assert_eq!(181 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),182 true183 );184 assert_eq!(185 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic(),186 true187 );188 assert_eq!(189 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),190 false191 );192 assert_eq!(193 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),194 false195 );196 assert_eq!(197 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),198 true199 );200 assert_eq!(201 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),202 true203 );204 assert_eq!(205 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic(),206 true207 );208 }209210 #[test]211 fn impl_abi_type_size() {212 const ABI_ALIGNMENT: usize = 32;213 assert_eq!(214 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::size(),215 ABI_ALIGNMENT216 );217 assert_eq!(218 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::size(),219 ABI_ALIGNMENT220 );221 assert_eq!(222 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::size(),223 ABI_ALIGNMENT * 2224 );225 assert_eq!(226 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::size(),227 ABI_ALIGNMENT * 2228 );229 assert_eq!(230 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::size(),231 ABI_ALIGNMENT * 2232 );233 assert_eq!(234 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size(),235 ABI_ALIGNMENT236 );237 assert_eq!(238 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size(),239 ABI_ALIGNMENT * 3240 );241 assert_eq!(242 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size(),243 ABI_ALIGNMENT244 );245 assert_eq!(246 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size(),247 ABI_ALIGNMENT * 3248 );249 assert_eq!(250 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size(),251 ABI_ALIGNMENT * 5252 );253 }254255 #[derive(AbiCoder, PartialEq, Debug)]256 struct TupleStruct1SimpleParam(u8);257258 #[derive(AbiCoder, PartialEq, Debug)]259 struct TupleStruct1DynamicParam(String);260261 #[derive(AbiCoder, PartialEq, Debug)]262 struct TupleStruct2SimpleParam(u8, u32);263264 #[derive(AbiCoder, PartialEq, Debug)]265 struct TupleStruct2DynamicParam(String, bytes);266267 #[derive(AbiCoder, PartialEq, Debug)]268 struct TupleStruct2MixedParam(u8, bytes);269270 #[derive(AbiCoder, PartialEq, Debug)]271 struct TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam);272273 #[derive(AbiCoder, PartialEq, Debug)]274 struct TupleStruct2DerivedSimpleParam(TupleStruct1SimpleParam, TupleStruct2SimpleParam);275276 #[derive(AbiCoder, PartialEq, Debug)]277 struct TupleStruct1DerivedDynamicParam(TupleStruct1DynamicParam);278279 #[derive(AbiCoder, PartialEq, Debug)]280 struct TupleStruct2DerivedDynamicParam(TupleStruct1DynamicParam, TupleStruct2DynamicParam);281282 /// Some docs283 /// At multi284 /// line285 #[derive(AbiCoder, PartialEq, Debug)]286 struct TupleStruct3DerivedMixedParam(287 /// Docs for A288 /// multi289 /// line290 TupleStruct1SimpleParam,291 /// Docs for B292 TupleStruct2DynamicParam,293 /// Docs for C294 TupleStruct2MixedParam,295 );296297 #[test]298 #[cfg(feature = "stubgen")]299 fn struct_collect_TupleStruct3DerivedMixedParam() {300 assert_eq!(301 <TupleStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::name(),302 "TupleStruct3DerivedMixedParam"303 );304 assert_eq!(305 <TupleStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::declaration(),306 r#"/// @dev Some docs307/// At multi308/// line309struct TupleStruct3DerivedMixedParam {310 /// @dev Docs for A311 /// multi312 /// line313 TupleStruct1SimpleParam field0;314 /// @dev Docs for B315 TupleStruct2DynamicParam field1;316 /// @dev Docs for C317 TupleStruct2MixedParam field2;318}319"#320 );321 }322323 #[test]324 fn impl_abi_type_signature_same_for_structs() {325 assert_eq!(326 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE327 .as_str()328 .unwrap(),329 <TupleStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE330 .as_str()331 .unwrap()332 );333 assert_eq!(334 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE335 .as_str()336 .unwrap(),337 <TupleStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE338 .as_str()339 .unwrap()340 );341 assert_eq!(342 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE343 .as_str()344 .unwrap(),345 <TupleStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE346 .as_str()347 .unwrap()348 );349 assert_eq!(350 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE351 .as_str()352 .unwrap(),353 <TupleStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE354 .as_str()355 .unwrap()356 );357 assert_eq!(358 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE359 .as_str()360 .unwrap(),361 <TupleStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE362 .as_str()363 .unwrap(),364 );365 assert_eq!(366 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE367 .as_str()368 .unwrap(),369 <TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE370 .as_str()371 .unwrap(),372 );373 assert_eq!(374 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE375 .as_str()376 .unwrap(),377 <TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE378 .as_str()379 .unwrap(),380 );381 assert_eq!(382 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE383 .as_str()384 .unwrap(),385 <TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE386 .as_str()387 .unwrap(),388 );389 assert_eq!(390 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE391 .as_str()392 .unwrap(),393 <TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE394 .as_str()395 .unwrap(),396 );397 assert_eq!(398 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE399 .as_str()400 .unwrap(),401 <TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE402 .as_str()403 .unwrap(),404 );405 }406407 #[test]408 fn impl_abi_type_is_dynamic_same_for_structs() {409 assert_eq!(410 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),411 <TupleStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic()412 );413 assert_eq!(414 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),415 <TupleStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic()416 );417 assert_eq!(418 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),419 <TupleStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic()420 );421 assert_eq!(422 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),423 <TupleStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic()424 );425 assert_eq!(426 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic(),427 <TupleStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic()428 );429 assert_eq!(430 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),431 <TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic()432 );433 assert_eq!(434 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),435 <TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic()436 );437 assert_eq!(438 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),439 <TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic()440 );441 assert_eq!(442 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),443 <TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic()444 );445 assert_eq!(446 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic(),447 <TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic()448 );449 }450451 #[test]452 fn impl_abi_type_size_same_for_structs() {453 assert_eq!(454 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::size(),455 <TupleStruct1SimpleParam as evm_coder::abi::AbiType>::size()456 );457 assert_eq!(458 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::size(),459 <TupleStruct1DynamicParam as evm_coder::abi::AbiType>::size()460 );461 assert_eq!(462 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::size(),463 <TupleStruct2SimpleParam as evm_coder::abi::AbiType>::size()464 );465 assert_eq!(466 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::size(),467 <TupleStruct2DynamicParam as evm_coder::abi::AbiType>::size()468 );469 assert_eq!(470 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::size(),471 <TupleStruct2MixedParam as evm_coder::abi::AbiType>::size()472 );473 assert_eq!(474 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size(),475 <TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size()476 );477 assert_eq!(478 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size(),479 <TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size()480 );481 assert_eq!(482 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size(),483 <TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size()484 );485 assert_eq!(486 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size(),487 <TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size()488 );489 assert_eq!(490 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size(),491 <TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size()492 );493 }494495 const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;496497 fn test_impl<Tuple, TupleStruct, TypeStruct>(498 tuple_data: Tuple,499 tuple_struct_data: TupleStruct,500 type_struct_data: TypeStruct,501 ) where502 TypeStruct: evm_coder::abi::AbiWrite503 + evm_coder::abi::AbiRead504 + std::cmp::PartialEq505 + std::fmt::Debug,506 TupleStruct: evm_coder::abi::AbiWrite507 + evm_coder::abi::AbiRead508 + std::cmp::PartialEq509 + std::fmt::Debug,510 Tuple: evm_coder::abi::AbiWrite511 + evm_coder::abi::AbiRead512 + std::cmp::PartialEq513 + std::fmt::Debug,514 {515 let encoded_type_struct = test_abi_write_impl(&type_struct_data);516 let encoded_tuple_struct = test_abi_write_impl(&tuple_struct_data);517 let encoded_tuple = test_abi_write_impl(&tuple_data);518519 similar_asserts::assert_eq!(encoded_tuple, encoded_type_struct);520 similar_asserts::assert_eq!(encoded_tuple, encoded_tuple_struct);521522 {523 let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_tuple).unwrap();524 let restored_struct_data = <TypeStruct>::abi_read(&mut decoder).unwrap();525 assert_eq!(restored_struct_data, type_struct_data);526 }527 {528 let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_tuple).unwrap();529 let restored_struct_data = <TupleStruct>::abi_read(&mut decoder).unwrap();530 assert_eq!(restored_struct_data, tuple_struct_data);531 }532533 {534 let (_, mut decoder) =535 evm_coder::abi::AbiReader::new_call(&encoded_type_struct).unwrap();536 let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();537 assert_eq!(restored_tuple_data, tuple_data);538 }539 {540 let (_, mut decoder) =541 evm_coder::abi::AbiReader::new_call(&encoded_tuple_struct).unwrap();542 let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();543 assert_eq!(restored_tuple_data, tuple_data);544 }545 }546547 fn test_abi_write_impl<A>(data: &A) -> Vec<u8>548 where549 A: evm_coder::abi::AbiWrite550 + evm_coder::abi::AbiRead551 + std::cmp::PartialEq552 + std::fmt::Debug,553 {554 let mut writer = evm_coder::abi::AbiWriter::new_call(FUNCTION_IDENTIFIER);555 data.abi_write(&mut writer);556 let encoded_tuple = writer.finish();557 encoded_tuple558 }559560 #[test]561 fn codec_struct_1_simple() {562 let _a = 0xff;563 test_impl::<(u8,), TupleStruct1SimpleParam, TypeStruct1SimpleParam>(564 (_a,),565 TupleStruct1SimpleParam(_a),566 TypeStruct1SimpleParam { _a },567 );568 }569570 #[test]571 fn codec_struct_1_dynamic() {572 let _a: String = "some string".into();573 test_impl::<(String,), TupleStruct1DynamicParam, TypeStruct1DynamicParam>(574 (_a.clone(),),575 TupleStruct1DynamicParam(_a.clone()),576 TypeStruct1DynamicParam { _a },577 );578 }579580 #[test]581 fn codec_struct_1_derived_simple() {582 let _a: u8 = 0xff;583 test_impl::<((u8,),), TupleStruct1DerivedSimpleParam, TypeStruct1DerivedSimpleParam>(584 ((_a,),),585 TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam(_a)),586 TypeStruct1DerivedSimpleParam {587 _a: TypeStruct1SimpleParam { _a },588 },589 );590 }591592 #[test]593 fn codec_struct_1_derived_dynamic() {594 let _a: String = "some string".into();595 test_impl::<((String,),), TupleStruct1DerivedDynamicParam, TypeStruct1DerivedDynamicParam>(596 ((_a.clone(),),),597 TupleStruct1DerivedDynamicParam(TupleStruct1DynamicParam(_a.clone())),598 TypeStruct1DerivedDynamicParam {599 _a: TypeStruct1DynamicParam { _a },600 },601 );602 }603604 #[test]605 fn codec_struct_2_simple() {606 let _a = 0xff;607 let _b = 0xbeefbaba;608 test_impl::<(u8, u32), TupleStruct2SimpleParam, TypeStruct2SimpleParam>(609 (_a, _b),610 TupleStruct2SimpleParam(_a, _b),611 TypeStruct2SimpleParam { _a, _b },612 );613 }614615 #[test]616 fn codec_struct_2_dynamic() {617 let _a: String = "some string".into();618 let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);619 test_impl::<(String, bytes), TupleStruct2DynamicParam, TypeStruct2DynamicParam>(620 (_a.clone(), _b.clone()),621 TupleStruct2DynamicParam(_a.clone(), _b.clone()),622 TypeStruct2DynamicParam { _a, _b },623 );624 }625626 #[test]627 fn codec_struct_2_mixed() {628 let _a: u8 = 0xff;629 let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);630 test_impl::<(u8, bytes), TupleStruct2MixedParam, TypeStruct2MixedParam>(631 (_a.clone(), _b.clone()),632 TupleStruct2MixedParam(_a.clone(), _b.clone()),633 TypeStruct2MixedParam { _a, _b },634 );635 }636637 #[test]638 fn codec_struct_2_derived_simple() {639 let _a = 0xff;640 let _b = 0xbeefbaba;641 test_impl::<642 ((u8,), (u8, u32)),643 TupleStruct2DerivedSimpleParam,644 TypeStruct2DerivedSimpleParam,645 >(646 ((_a,), (_a, _b)),647 TupleStruct2DerivedSimpleParam(648 TupleStruct1SimpleParam(_a),649 TupleStruct2SimpleParam(_a, _b),650 ),651 TypeStruct2DerivedSimpleParam {652 _a: TypeStruct1SimpleParam { _a },653 _b: TypeStruct2SimpleParam { _a, _b },654 },655 );656 }657658 #[test]659 fn codec_struct_2_derived_dynamic() {660 let _a = "some string".to_string();661 let _b = bytes(vec![0x11, 0x22, 0x33]);662 test_impl::<663 ((String,), (String, bytes)),664 TupleStruct2DerivedDynamicParam,665 TypeStruct2DerivedDynamicParam,666 >(667 ((_a.clone(),), (_a.clone(), _b.clone())),668 TupleStruct2DerivedDynamicParam(669 TupleStruct1DynamicParam(_a.clone()),670 TupleStruct2DynamicParam(_a.clone(), _b.clone()),671 ),672 TypeStruct2DerivedDynamicParam {673 _a: TypeStruct1DynamicParam { _a: _a.clone() },674 _b: TypeStruct2DynamicParam { _a, _b },675 },676 );677 }678679 #[test]680 fn codec_struct_3_derived_mixed() {681 let int = 0xff;682 let by = bytes(vec![0x11, 0x22, 0x33]);683 let string = "some string".to_string();684 test_impl::<685 ((u8,), (String, bytes), (u8, bytes)),686 TupleStruct3DerivedMixedParam,687 TypeStruct3DerivedMixedParam,688 >(689 ((int,), (string.clone(), by.clone()), (int, by.clone())),690 TupleStruct3DerivedMixedParam(691 TupleStruct1SimpleParam(int),692 TupleStruct2DynamicParam(string.clone(), by.clone()),693 TupleStruct2MixedParam(int, by.clone()),694 ),695 TypeStruct3DerivedMixedParam {696 _a: TypeStruct1SimpleParam { _a: int },697 _b: TypeStruct2DynamicParam {698 _a: string.clone(),699 _b: by.clone(),700 },701 _c: TypeStruct2MixedParam { _a: int, _b: by },702 },703 );704 }705706 #[derive(AbiCoder, PartialEq, Debug)]707 struct TypeStruct2SimpleStruct1Simple {708 _a: TypeStruct2SimpleParam,709 _b: TypeStruct2SimpleParam,710 _c: u8,711 }712 #[derive(AbiCoder, PartialEq, Debug)]713 struct TupleStruct2SimpleStruct1Simple(TupleStruct2SimpleParam, TupleStruct2SimpleParam, u8);714715 #[test]716 fn codec_struct_2_struct_simple_1_simple() {717 let _a = 0xff;718 let _b = 0xbeefbaba;719 test_impl::<720 ((u8, u32), (u8, u32), u8),721 TupleStruct2SimpleStruct1Simple,722 TypeStruct2SimpleStruct1Simple,723 >(724 ((_a, _b), (_a, _b), _a),725 TupleStruct2SimpleStruct1Simple(726 TupleStruct2SimpleParam(_a, _b),727 TupleStruct2SimpleParam(_a, _b),728 _a,729 ),730 TypeStruct2SimpleStruct1Simple {731 _a: TypeStruct2SimpleParam { _a, _b },732 _b: TypeStruct2SimpleParam { _a, _b },733 _c: _a,734 },735 );736 }737}738739mod test_enum {740 use evm_coder::AbiCoder;741742 #[derive(AbiCoder)]743 #[repr(u8)]744 enum Color {745 Red,746 Green,747 Blue,748 }749750 #[test]751 fn empty() {}752753 #[test]754 fn bad_enums() {755 let t = trybuild::TestCases::new();756 t.compile_fail("tests/build_failed/abi_derive_enum_generation.rs");757 }758}1mod test_struct {2 use evm_coder_procedural::AbiCoder;3 use evm_coder::types::bytes;45 #[test]6 fn empty_struct() {7 let t = trybuild::TestCases::new();8 t.compile_fail("tests/build_failed/abi_derive_struct_generation.rs");9 }1011 #[derive(AbiCoder, PartialEq, Debug)]12 struct TypeStruct1SimpleParam {13 _a: u8,14 }1516 #[derive(AbiCoder, PartialEq, Debug)]17 struct TypeStruct1DynamicParam {18 _a: String,19 }2021 #[derive(AbiCoder, PartialEq, Debug)]22 struct TypeStruct2SimpleParam {23 _a: u8,24 _b: u32,25 }2627 #[derive(AbiCoder, PartialEq, Debug)]28 struct TypeStruct2DynamicParam {29 _a: String,30 _b: bytes,31 }3233 #[derive(AbiCoder, PartialEq, Debug)]34 struct TypeStruct2MixedParam {35 _a: u8,36 _b: bytes,37 }3839 #[derive(AbiCoder, PartialEq, Debug)]40 struct TypeStruct1DerivedSimpleParam {41 _a: TypeStruct1SimpleParam,42 }4344 #[derive(AbiCoder, PartialEq, Debug)]45 struct TypeStruct2DerivedSimpleParam {46 _a: TypeStruct1SimpleParam,47 _b: TypeStruct2SimpleParam,48 }4950 #[derive(AbiCoder, PartialEq, Debug)]51 struct TypeStruct1DerivedDynamicParam {52 _a: TypeStruct1DynamicParam,53 }5455 #[derive(AbiCoder, PartialEq, Debug)]56 struct TypeStruct2DerivedDynamicParam {57 _a: TypeStruct1DynamicParam,58 _b: TypeStruct2DynamicParam,59 }6061 /// Some docs62 /// At multi63 /// line64 #[derive(AbiCoder, PartialEq, Debug)]65 struct TypeStruct3DerivedMixedParam {66 /// Docs for A67 /// multi68 /// line69 _a: TypeStruct1SimpleParam,70 /// Docs for B71 _b: TypeStruct2DynamicParam,72 /// Docs for C73 _c: TypeStruct2MixedParam,74 }7576 #[test]77 #[cfg(feature = "stubgen")]78 fn struct_collect_type_struct3_derived_mixed_param() {79 assert_eq!(80 <TypeStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::name(),81 "TypeStruct3DerivedMixedParam"82 );83 assert_eq!(84 <TypeStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::declaration(),85 r#"/// @dev Some docs86/// At multi87/// line88struct TypeStruct3DerivedMixedParam {89 /// @dev Docs for A90 /// multi91 /// line92 TypeStruct1SimpleParam _a;93 /// @dev Docs for B94 TypeStruct2DynamicParam _b;95 /// @dev Docs for C96 TypeStruct2MixedParam _c;97}98"#99 );100 }101102 #[test]103 fn impl_abi_type_signature() {104 assert_eq!(105 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE106 .as_str()107 .unwrap(),108 "(uint8)"109 );110 assert_eq!(111 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE112 .as_str()113 .unwrap(),114 "(string)"115 );116 assert_eq!(117 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE118 .as_str()119 .unwrap(),120 "(uint8,uint32)"121 );122 assert_eq!(123 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE124 .as_str()125 .unwrap(),126 "(string,bytes)"127 );128 assert_eq!(129 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE130 .as_str()131 .unwrap(),132 "(uint8,bytes)"133 );134 assert_eq!(135 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE136 .as_str()137 .unwrap(),138 "((uint8))"139 );140 assert_eq!(141 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE142 .as_str()143 .unwrap(),144 "((uint8),(uint8,uint32))"145 );146 assert_eq!(147 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE148 .as_str()149 .unwrap(),150 "((string))"151 );152 assert_eq!(153 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE154 .as_str()155 .unwrap(),156 "((string),(string,bytes))"157 );158 assert_eq!(159 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE160 .as_str()161 .unwrap(),162 "((uint8),(string,bytes),(uint8,bytes))"163 );164 }165166 #[test]167 fn impl_abi_type_is_dynamic() {168 assert_eq!(169 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),170 false171 );172 assert_eq!(173 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),174 true175 );176 assert_eq!(177 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),178 false179 );180 assert_eq!(181 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),182 true183 );184 assert_eq!(185 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic(),186 true187 );188 assert_eq!(189 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),190 false191 );192 assert_eq!(193 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),194 false195 );196 assert_eq!(197 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),198 true199 );200 assert_eq!(201 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),202 true203 );204 assert_eq!(205 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic(),206 true207 );208 }209210 #[test]211 fn impl_abi_type_size() {212 const ABI_ALIGNMENT: usize = 32;213 assert_eq!(214 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::size(),215 ABI_ALIGNMENT216 );217 assert_eq!(218 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::size(),219 ABI_ALIGNMENT220 );221 assert_eq!(222 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::size(),223 ABI_ALIGNMENT * 2224 );225 assert_eq!(226 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::size(),227 ABI_ALIGNMENT * 2228 );229 assert_eq!(230 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::size(),231 ABI_ALIGNMENT * 2232 );233 assert_eq!(234 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size(),235 ABI_ALIGNMENT236 );237 assert_eq!(238 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size(),239 ABI_ALIGNMENT * 3240 );241 assert_eq!(242 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size(),243 ABI_ALIGNMENT244 );245 assert_eq!(246 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size(),247 ABI_ALIGNMENT * 3248 );249 assert_eq!(250 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size(),251 ABI_ALIGNMENT * 5252 );253 }254255 #[derive(AbiCoder, PartialEq, Debug)]256 struct TupleStruct1SimpleParam(u8);257258 #[derive(AbiCoder, PartialEq, Debug)]259 struct TupleStruct1DynamicParam(String);260261 #[derive(AbiCoder, PartialEq, Debug)]262 struct TupleStruct2SimpleParam(u8, u32);263264 #[derive(AbiCoder, PartialEq, Debug)]265 struct TupleStruct2DynamicParam(String, bytes);266267 #[derive(AbiCoder, PartialEq, Debug)]268 struct TupleStruct2MixedParam(u8, bytes);269270 #[derive(AbiCoder, PartialEq, Debug)]271 struct TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam);272273 #[derive(AbiCoder, PartialEq, Debug)]274 struct TupleStruct2DerivedSimpleParam(TupleStruct1SimpleParam, TupleStruct2SimpleParam);275276 #[derive(AbiCoder, PartialEq, Debug)]277 struct TupleStruct1DerivedDynamicParam(TupleStruct1DynamicParam);278279 #[derive(AbiCoder, PartialEq, Debug)]280 struct TupleStruct2DerivedDynamicParam(TupleStruct1DynamicParam, TupleStruct2DynamicParam);281282 /// Some docs283 /// At multi284 /// line285 #[derive(AbiCoder, PartialEq, Debug)]286 struct TupleStruct3DerivedMixedParam(287 /// Docs for A288 /// multi289 /// line290 TupleStruct1SimpleParam,291 /// Docs for B292 TupleStruct2DynamicParam,293 /// Docs for C294 TupleStruct2MixedParam,295 );296297 #[test]298 #[cfg(feature = "stubgen")]299 fn struct_collect_tuple_struct3_derived_mixed_param() {300 assert_eq!(301 <TupleStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::name(),302 "TupleStruct3DerivedMixedParam"303 );304 assert_eq!(305 <TupleStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::declaration(),306 r#"/// @dev Some docs307/// At multi308/// line309struct TupleStruct3DerivedMixedParam {310 /// @dev Docs for A311 /// multi312 /// line313 TupleStruct1SimpleParam field0;314 /// @dev Docs for B315 TupleStruct2DynamicParam field1;316 /// @dev Docs for C317 TupleStruct2MixedParam field2;318}319"#320 );321 }322323 #[test]324 fn impl_abi_type_signature_same_for_structs() {325 assert_eq!(326 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE327 .as_str()328 .unwrap(),329 <TupleStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE330 .as_str()331 .unwrap()332 );333 assert_eq!(334 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE335 .as_str()336 .unwrap(),337 <TupleStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE338 .as_str()339 .unwrap()340 );341 assert_eq!(342 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE343 .as_str()344 .unwrap(),345 <TupleStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE346 .as_str()347 .unwrap()348 );349 assert_eq!(350 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE351 .as_str()352 .unwrap(),353 <TupleStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE354 .as_str()355 .unwrap()356 );357 assert_eq!(358 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE359 .as_str()360 .unwrap(),361 <TupleStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE362 .as_str()363 .unwrap(),364 );365 assert_eq!(366 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE367 .as_str()368 .unwrap(),369 <TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE370 .as_str()371 .unwrap(),372 );373 assert_eq!(374 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE375 .as_str()376 .unwrap(),377 <TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE378 .as_str()379 .unwrap(),380 );381 assert_eq!(382 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE383 .as_str()384 .unwrap(),385 <TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE386 .as_str()387 .unwrap(),388 );389 assert_eq!(390 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE391 .as_str()392 .unwrap(),393 <TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE394 .as_str()395 .unwrap(),396 );397 assert_eq!(398 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE399 .as_str()400 .unwrap(),401 <TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE402 .as_str()403 .unwrap(),404 );405 }406407 #[test]408 fn impl_abi_type_is_dynamic_same_for_structs() {409 assert_eq!(410 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),411 <TupleStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic()412 );413 assert_eq!(414 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),415 <TupleStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic()416 );417 assert_eq!(418 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),419 <TupleStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic()420 );421 assert_eq!(422 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),423 <TupleStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic()424 );425 assert_eq!(426 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic(),427 <TupleStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic()428 );429 assert_eq!(430 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),431 <TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic()432 );433 assert_eq!(434 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),435 <TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic()436 );437 assert_eq!(438 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),439 <TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic()440 );441 assert_eq!(442 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),443 <TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic()444 );445 assert_eq!(446 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic(),447 <TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic()448 );449 }450451 #[test]452 fn impl_abi_type_size_same_for_structs() {453 assert_eq!(454 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::size(),455 <TupleStruct1SimpleParam as evm_coder::abi::AbiType>::size()456 );457 assert_eq!(458 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::size(),459 <TupleStruct1DynamicParam as evm_coder::abi::AbiType>::size()460 );461 assert_eq!(462 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::size(),463 <TupleStruct2SimpleParam as evm_coder::abi::AbiType>::size()464 );465 assert_eq!(466 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::size(),467 <TupleStruct2DynamicParam as evm_coder::abi::AbiType>::size()468 );469 assert_eq!(470 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::size(),471 <TupleStruct2MixedParam as evm_coder::abi::AbiType>::size()472 );473 assert_eq!(474 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size(),475 <TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size()476 );477 assert_eq!(478 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size(),479 <TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size()480 );481 assert_eq!(482 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size(),483 <TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size()484 );485 assert_eq!(486 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size(),487 <TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size()488 );489 assert_eq!(490 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size(),491 <TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size()492 );493 }494495 const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;496497 fn test_impl<Tuple, TupleStruct, TypeStruct>(498 tuple_data: Tuple,499 tuple_struct_data: TupleStruct,500 type_struct_data: TypeStruct,501 ) where502 TypeStruct: evm_coder::abi::AbiWrite503 + evm_coder::abi::AbiRead504 + std::cmp::PartialEq505 + std::fmt::Debug,506 TupleStruct: evm_coder::abi::AbiWrite507 + evm_coder::abi::AbiRead508 + std::cmp::PartialEq509 + std::fmt::Debug,510 Tuple: evm_coder::abi::AbiWrite511 + evm_coder::abi::AbiRead512 + std::cmp::PartialEq513 + std::fmt::Debug,514 {515 let encoded_type_struct = test_abi_write_impl(&type_struct_data);516 let encoded_tuple_struct = test_abi_write_impl(&tuple_struct_data);517 let encoded_tuple = test_abi_write_impl(&tuple_data);518519 similar_asserts::assert_eq!(encoded_tuple, encoded_type_struct);520 similar_asserts::assert_eq!(encoded_tuple, encoded_tuple_struct);521522 {523 let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_tuple).unwrap();524 let restored_struct_data = <TypeStruct>::abi_read(&mut decoder).unwrap();525 assert_eq!(restored_struct_data, type_struct_data);526 }527 {528 let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_tuple).unwrap();529 let restored_struct_data = <TupleStruct>::abi_read(&mut decoder).unwrap();530 assert_eq!(restored_struct_data, tuple_struct_data);531 }532533 {534 let (_, mut decoder) =535 evm_coder::abi::AbiReader::new_call(&encoded_type_struct).unwrap();536 let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();537 assert_eq!(restored_tuple_data, tuple_data);538 }539 {540 let (_, mut decoder) =541 evm_coder::abi::AbiReader::new_call(&encoded_tuple_struct).unwrap();542 let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();543 assert_eq!(restored_tuple_data, tuple_data);544 }545 }546547 fn test_abi_write_impl<A>(data: &A) -> Vec<u8>548 where549 A: evm_coder::abi::AbiWrite550 + evm_coder::abi::AbiRead551 + std::cmp::PartialEq552 + std::fmt::Debug,553 {554 let mut writer = evm_coder::abi::AbiWriter::new_call(FUNCTION_IDENTIFIER);555 data.abi_write(&mut writer);556 let encoded_tuple = writer.finish();557 encoded_tuple558 }559560 #[test]561 fn codec_struct_1_simple() {562 let _a = 0xff;563 test_impl::<(u8,), TupleStruct1SimpleParam, TypeStruct1SimpleParam>(564 (_a,),565 TupleStruct1SimpleParam(_a),566 TypeStruct1SimpleParam { _a },567 );568 }569570 #[test]571 fn codec_struct_1_dynamic() {572 let _a: String = "some string".into();573 test_impl::<(String,), TupleStruct1DynamicParam, TypeStruct1DynamicParam>(574 (_a.clone(),),575 TupleStruct1DynamicParam(_a.clone()),576 TypeStruct1DynamicParam { _a },577 );578 }579580 #[test]581 fn codec_struct_1_derived_simple() {582 let _a: u8 = 0xff;583 test_impl::<((u8,),), TupleStruct1DerivedSimpleParam, TypeStruct1DerivedSimpleParam>(584 ((_a,),),585 TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam(_a)),586 TypeStruct1DerivedSimpleParam {587 _a: TypeStruct1SimpleParam { _a },588 },589 );590 }591592 #[test]593 fn codec_struct_1_derived_dynamic() {594 let _a: String = "some string".into();595 test_impl::<((String,),), TupleStruct1DerivedDynamicParam, TypeStruct1DerivedDynamicParam>(596 ((_a.clone(),),),597 TupleStruct1DerivedDynamicParam(TupleStruct1DynamicParam(_a.clone())),598 TypeStruct1DerivedDynamicParam {599 _a: TypeStruct1DynamicParam { _a },600 },601 );602 }603604 #[test]605 fn codec_struct_2_simple() {606 let _a = 0xff;607 let _b = 0xbeefbaba;608 test_impl::<(u8, u32), TupleStruct2SimpleParam, TypeStruct2SimpleParam>(609 (_a, _b),610 TupleStruct2SimpleParam(_a, _b),611 TypeStruct2SimpleParam { _a, _b },612 );613 }614615 #[test]616 fn codec_struct_2_dynamic() {617 let _a: String = "some string".into();618 let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);619 test_impl::<(String, bytes), TupleStruct2DynamicParam, TypeStruct2DynamicParam>(620 (_a.clone(), _b.clone()),621 TupleStruct2DynamicParam(_a.clone(), _b.clone()),622 TypeStruct2DynamicParam { _a, _b },623 );624 }625626 #[test]627 fn codec_struct_2_mixed() {628 let _a: u8 = 0xff;629 let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);630 test_impl::<(u8, bytes), TupleStruct2MixedParam, TypeStruct2MixedParam>(631 (_a.clone(), _b.clone()),632 TupleStruct2MixedParam(_a.clone(), _b.clone()),633 TypeStruct2MixedParam { _a, _b },634 );635 }636637 #[test]638 fn codec_struct_2_derived_simple() {639 let _a = 0xff;640 let _b = 0xbeefbaba;641 test_impl::<642 ((u8,), (u8, u32)),643 TupleStruct2DerivedSimpleParam,644 TypeStruct2DerivedSimpleParam,645 >(646 ((_a,), (_a, _b)),647 TupleStruct2DerivedSimpleParam(648 TupleStruct1SimpleParam(_a),649 TupleStruct2SimpleParam(_a, _b),650 ),651 TypeStruct2DerivedSimpleParam {652 _a: TypeStruct1SimpleParam { _a },653 _b: TypeStruct2SimpleParam { _a, _b },654 },655 );656 }657658 #[test]659 fn codec_struct_2_derived_dynamic() {660 let _a = "some string".to_string();661 let _b = bytes(vec![0x11, 0x22, 0x33]);662 test_impl::<663 ((String,), (String, bytes)),664 TupleStruct2DerivedDynamicParam,665 TypeStruct2DerivedDynamicParam,666 >(667 ((_a.clone(),), (_a.clone(), _b.clone())),668 TupleStruct2DerivedDynamicParam(669 TupleStruct1DynamicParam(_a.clone()),670 TupleStruct2DynamicParam(_a.clone(), _b.clone()),671 ),672 TypeStruct2DerivedDynamicParam {673 _a: TypeStruct1DynamicParam { _a: _a.clone() },674 _b: TypeStruct2DynamicParam { _a, _b },675 },676 );677 }678679 #[test]680 fn codec_struct_3_derived_mixed() {681 let int = 0xff;682 let by = bytes(vec![0x11, 0x22, 0x33]);683 let string = "some string".to_string();684 test_impl::<685 ((u8,), (String, bytes), (u8, bytes)),686 TupleStruct3DerivedMixedParam,687 TypeStruct3DerivedMixedParam,688 >(689 ((int,), (string.clone(), by.clone()), (int, by.clone())),690 TupleStruct3DerivedMixedParam(691 TupleStruct1SimpleParam(int),692 TupleStruct2DynamicParam(string.clone(), by.clone()),693 TupleStruct2MixedParam(int, by.clone()),694 ),695 TypeStruct3DerivedMixedParam {696 _a: TypeStruct1SimpleParam { _a: int },697 _b: TypeStruct2DynamicParam {698 _a: string.clone(),699 _b: by.clone(),700 },701 _c: TypeStruct2MixedParam { _a: int, _b: by },702 },703 );704 }705706 #[derive(AbiCoder, PartialEq, Debug)]707 struct TypeStruct2SimpleStruct1Simple {708 _a: TypeStruct2SimpleParam,709 _b: TypeStruct2SimpleParam,710 _c: u8,711 }712 #[derive(AbiCoder, PartialEq, Debug)]713 struct TupleStruct2SimpleStruct1Simple(TupleStruct2SimpleParam, TupleStruct2SimpleParam, u8);714715 #[test]716 fn codec_struct_2_struct_simple_1_simple() {717 let _a = 0xff;718 let _b = 0xbeefbaba;719 test_impl::<720 ((u8, u32), (u8, u32), u8),721 TupleStruct2SimpleStruct1Simple,722 TypeStruct2SimpleStruct1Simple,723 >(724 ((_a, _b), (_a, _b), _a),725 TupleStruct2SimpleStruct1Simple(726 TupleStruct2SimpleParam(_a, _b),727 TupleStruct2SimpleParam(_a, _b),728 _a,729 ),730 TypeStruct2SimpleStruct1Simple {731 _a: TypeStruct2SimpleParam { _a, _b },732 _b: TypeStruct2SimpleParam { _a, _b },733 _c: _a,734 },735 );736 }737}738739mod test_enum {740 use evm_coder::AbiCoder;741742 #[derive(AbiCoder, Default)]743 #[repr(u8)]744 enum Color {745 Red,746 Green,747 #[default]748 Blue,749 }750751 #[test]752 fn empty() {}753754 #[test]755 fn bad_enums() {756 let t = trybuild::TestCases::new();757 t.compile_fail("tests/build_failed/abi_derive_enum_generation.rs");758 }759}