difftreelog
misk: add docs for enums
in: master
2 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
@@ -14,7 +14,7 @@
ast: &syn::DeriveInput,
) -> syn::Result<proc_macro2::TokenStream> {
let name = &ast.ident;
- let docs = extract_docs(&ast.attrs)?;
+ let docs = extract_docs(&ast.attrs, true)?;
let (is_named_fields, field_names, field_types, field_docs, params_count) = match ds.fields {
syn::Fields::Named(ref fields) => Ok((
true,
@@ -70,8 +70,10 @@
) -> syn::Result<proc_macro2::TokenStream> {
let name = &ast.ident;
check_repr_u8(name, &ast.attrs)?;
+ let docs = extract_docs(&ast.attrs, true)?;
let option_count = check_and_count_option(de)?;
let enum_options = de.variants.iter().map(|v| &v.ident);
+ let enum_options_docs = de.variants.iter().map(|v| extract_docs(&v.attrs, false));
let from = impl_enum_from_u8(name, enum_options.clone());
let solidity_option = impl_solidity_option(name, enum_options.clone());
@@ -80,8 +82,13 @@
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);
- let solidity_struct_collect =
- impl_enum_solidity_struct_collect(name, enum_options, option_count);
+ let solidity_struct_collect = impl_enum_solidity_struct_collect(
+ name,
+ enum_options,
+ option_count,
+ enum_options_docs,
+ &docs,
+ );
Ok(quote! {
#from
@@ -206,15 +213,23 @@
name: &syn::Ident,
enum_options: impl Iterator<Item = &'a syn::Ident>,
option_count: usize,
+ enum_options_docs: impl Iterator<Item = syn::Result<Vec<proc_macro2::TokenStream>>>,
+ docs: &[proc_macro2::TokenStream],
) -> 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");
- }
- });
+ let enum_options = enum_options
+ .zip(enum_options_docs)
+ .enumerate()
+ .map(|(i, (opt, doc))| {
+ let opt = proc_macro2::Literal::string(opt.to_string().as_str());
+ let doc = doc.expect("Doc parsing error");
+ let comma = if i != option_count - 1 { "," } else { "" };
+ quote! {
+ #(#doc)*
+ writeln!(str, "\t{}{}", #opt, #comma).expect("Enum format option");
+ }
+ });
+
quote!(
#[cfg(feature = "stubgen")]
impl ::evm_coder::solidity::StructCollect for #name {
@@ -226,7 +241,7 @@
use std::fmt::Write;
let mut str = String::new();
- // #(#docs)*
+ #(#docs)*
writeln!(str, "enum {} {{", <Self as ::evm_coder::solidity::StructCollect>::name()).unwrap();
#(#enum_options)*
writeln!(str, "}}").unwrap();
@@ -384,7 +399,10 @@
}
}
-fn extract_docs(attrs: &[syn::Attribute]) -> syn::Result<Vec<String>> {
+fn extract_docs(
+ attrs: &[syn::Attribute],
+ is_general: bool,
+) -> syn::Result<Vec<proc_macro2::TokenStream>> {
attrs
.iter()
.filter_map(|attr| {
@@ -405,6 +423,16 @@
}
None
})
+ .enumerate()
+ .map(|(i, doc)| {
+ let doc = doc?;
+ let doc = doc.trim();
+ let dev = if i == 0 { " @dev" } else { "" };
+ let tab = if is_general { "" } else { "\t" };
+ Ok(quote! {
+ writeln!(str, "{}///{} {}", #tab, #dev, #doc).unwrap();
+ })
+ })
.collect()
}
@@ -423,8 +451,8 @@
&field.ty
}
-fn map_field_to_doc(field: &syn::Field) -> Result<Vec<std::string::String>, syn::Error> {
- extract_docs(&field.attrs)
+fn map_field_to_doc(field: &syn::Field) -> syn::Result<Vec<proc_macro2::TokenStream>> {
+ extract_docs(&field.attrs, false)
}
fn impl_can_be_placed_in_vec(ident: &syn::Ident) -> proc_macro2::TokenStream {
@@ -556,8 +584,8 @@
name: &syn::Ident,
field_names: impl Iterator<Item = proc_macro2::Ident> + Clone,
field_types: impl Iterator<Item = &'a syn::Type> + Clone,
- field_docs: impl Iterator<Item = syn::Result<Vec<String>>> + Clone,
- docs: &[String],
+ field_docs: impl Iterator<Item = syn::Result<Vec<proc_macro2::TokenStream>>> + Clone,
+ docs: &[proc_macro2::TokenStream],
) -> syn::Result<proc_macro2::TokenStream> {
let string_name = name.to_string();
let name_type = field_names
@@ -565,16 +593,7 @@
.zip(field_types)
.zip(field_docs)
.map(|((name, ty), doc)| {
- let field_docs = match doc {
- Ok(doc) => doc.into_iter().enumerate().map(|(i, doc)| {
- let doc = doc.trim();
- let dev = if i == 0 { " @dev" } else { "" };
- quote! {
- writeln!(str, "\t///{} {}", #dev, #doc).unwrap();
- }
- }),
- Err(e) => unreachable!("{:?}", e),
- };
+ let field_docs = doc.expect("Doc parse error");
let name = format!("{}", name);
quote!(
#(#field_docs)*
@@ -582,13 +601,6 @@
writeln!(str, "{};", #name).unwrap();
)
});
- let docs = docs.iter().enumerate().map(|(i, doc)| {
- let doc = doc.trim();
- let dev = if i == 0 { " @dev" } else { "" };
- quote! {
- writeln!(str, "///{} {}", #dev, #doc).unwrap();
- }
- });
Ok(quote! {
#[cfg(feature = "stubgen")]
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_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 /// Some docs743 /// At multi744 /// line745 #[derive(AbiCoder, Debug, PartialEq, Default)]746 #[repr(u8)]747 enum Color {748 /// Docs for Red749 /// multi750 /// line751 Red,752 /// Docs for Green753 Green,754 /// Docs for Blue755 #[default]756 Blue,757 }758759 #[test]760 fn empty() {}761762 #[test]763 fn bad_enums() {764 let t = trybuild::TestCases::new();765 t.compile_fail("tests/build_failed/abi_derive_enum_generation.rs");766 }767768 #[test]769 fn impl_abi_type_signature_same_for_structs() {770 assert_eq!(771 <Color as evm_coder::abi::AbiType>::SIGNATURE772 .as_str()773 .unwrap(),774 <u8 as evm_coder::abi::AbiType>::SIGNATURE.as_str().unwrap()775 );776 }777778 #[test]779 fn impl_abi_type_is_dynamic_same_for_structs() {780 assert_eq!(781 <Color as evm_coder::abi::AbiType>::is_dynamic(),782 <u8 as evm_coder::abi::AbiType>::is_dynamic()783 );784 }785786 #[test]787 fn impl_abi_type_size_same_for_structs() {788 assert_eq!(789 <Color as evm_coder::abi::AbiType>::size(),790 <u8 as evm_coder::abi::AbiType>::size()791 );792 }793794 #[test]795 fn test_coder() {796 const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;797798 let encoded_enum = {799 let mut writer = evm_coder::abi::AbiWriter::new_call(FUNCTION_IDENTIFIER);800 <Color as evm_coder::abi::AbiWrite>::abi_write(&Color::Green, &mut writer);801 writer.finish()802 };803804 let encoded_u8 = {805 let mut writer = evm_coder::abi::AbiWriter::new_call(FUNCTION_IDENTIFIER);806 <u8 as evm_coder::abi::AbiWrite>::abi_write(&(Color::Green as u8), &mut writer);807 writer.finish()808 };809810 similar_asserts::assert_eq!(encoded_enum, encoded_u8);811812 {813 let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_enum).unwrap();814 let restored_enum_data =815 <Color as evm_coder::abi::AbiRead>::abi_read(&mut decoder).unwrap();816 assert_eq!(restored_enum_data, Color::Green);817 }818 }819820 #[test]821 #[cfg(feature = "stubgen")]822 fn struct_collect_enum() {823 assert_eq!(824 <Color as ::evm_coder::solidity::StructCollect>::name(),825 "Color"826 );827 assert_eq!(828 <Color as ::evm_coder::solidity::StructCollect>::declaration(),829 r#"/// @dev Some docs830/// At multi831/// line832enum Color {833 /// @dev Docs for A834 /// multi835 /// line836 Red,837 /// @dev Docs for B838 Green,839 /// @dev Docs for C840 Blue841}842"#843 );844 }845}