git.delta.rocks / unique-network / refs/commits / 7eec33a3cc63

difftreelog

fix AbiRead implementations

Trubnikov Sergey2022-11-16parent: #b3e1096.patch.diff
in: master

5 files changed

modifiedcrates/evm-coder/procedural/src/abi_derive.rsdiffbeforeafterboth
1use quote::quote;1use quote::quote;
22
3pub(crate) fn impl_abi_macro(ast: &syn::DeriveInput) -> syn::Result<proc_macro2::TokenStream> {3pub(crate) fn impl_abi_macro(ast: &syn::DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
4 // dbg!(ast);
5 let name = &ast.ident;4 let name = &ast.ident;
6 let (is_named_fields, field_names, field_types, params_count) = match &ast.data {5 let (is_named_fields, field_names, field_types, params_count) = match &ast.data {
7 syn::Data::Struct(ds) => match ds.fields {6 syn::Data::Struct(ds) => match ds.fields {
31 let abi_type = impl_abi_type(name, field_types.clone());30 let abi_type = impl_abi_type(name, field_types.clone());
32 let abi_read = impl_abi_read(name, is_named_fields, field_names.clone(), field_types);31 let abi_read = impl_abi_read(name, is_named_fields, field_names.clone(), field_types);
33 let abi_write = impl_abi_write(name, is_named_fields, params_count, field_names);32 let abi_write = impl_abi_write(name, is_named_fields, params_count, field_names);
34 println!("{}", abi_write);33
35 Ok(quote! {34 Ok(quote! {
36 #can_be_plcaed_in_vec35 #can_be_plcaed_in_vec
37 #abi_type36 #abi_type
112 quote!(111 quote!(
113 impl ::evm_coder::abi::AbiRead for #name {112 impl ::evm_coder::abi::AbiRead for #name {
114 fn abi_read(reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Self> {113 fn abi_read(reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Self> {
115 let size = if !<Self as ::evm_coder::abi::AbiType>::is_dynamic() {114 let is_dynamic = <Self as ::evm_coder::abi::AbiType>::is_dynamic();
115 let size = if !is_dynamic {
116 Some(<Self as ::evm_coder::abi::AbiType>::size())116 Some(<Self as ::evm_coder::abi::AbiType>::size())
117 } else {117 } else {
118 None118 None
119 };119 };
120 let mut subresult = reader.subresult(size)?;120 let mut subresult = reader.subresult(size)?;
121 #(121 #(
122 let #field_names = <#field_types as ::evm_coder::abi::AbiRead>::abi_read(&mut subresult)?;122 let #field_names = {
123 let value = <#field_types as ::evm_coder::abi::AbiRead>::abi_read(&mut subresult)?;
124 if !is_dynamic {subresult.seek(<#field_types as ::evm_coder::abi::AbiType>::size())};
125 value
126 };
123 )*127 )*
124128
125 #struct_constructor129 #struct_constructor
modifiedcrates/evm-coder/src/abi/impls.rsdiffbeforeafterboth
92 }92 }
93}93}
9494
95impl<R: AbiRead + sealed::CanBePlacedInVec> AbiRead for Vec<R> {95impl<R: AbiType + AbiRead + sealed::CanBePlacedInVec> AbiRead for Vec<R> {
96 fn abi_read(reader: &mut AbiReader) -> Result<Vec<R>> {96 fn abi_read(reader: &mut AbiReader) -> Result<Vec<R>> {
97 let mut sub = reader.subresult(None)?;97 let mut sub = reader.subresult(None)?;
98 let size = sub.uint32()? as usize;98 let size = sub.uint32()? as usize;
99 sub.subresult_offset = sub.offset;99 sub.subresult_offset = sub.offset;
100 let mut out = Vec::with_capacity(size);100 let mut out = Vec::with_capacity(size);
101 for _ in 0..size {101 for _ in 0..size {
102 out.push(<R>::abi_read(&mut sub)?);102 out.push(<R>::abi_read(&mut sub)?);
103 if !<R>::is_dynamic() {
104 sub.subresult_offset += <R>::size()
105 };
103 }106 }
104 Ok(out)107 Ok(out)
105 }108 }
295298
296 impl<$($ident),+> AbiRead for ($($ident,)+)299 impl<$($ident),+> AbiRead for ($($ident,)+)
297 where300 where
298 $($ident: AbiRead,)+301 $($ident: AbiRead + AbiType,)+
299 ($($ident,)+): AbiType,302 ($($ident,)+): AbiType,
300 {303 {
301 fn abi_read(reader: &mut AbiReader) -> Result<($($ident,)+)> {304 fn abi_read(reader: &mut AbiReader) -> Result<($($ident,)+)> {
302 let size = if !<($($ident,)+)>::is_dynamic() { Some(<($($ident,)+)>::size()) } else { None };305 let is_dynamic = <($($ident,)+)>::is_dynamic();
306 let size = if !is_dynamic { Some(<($($ident,)+)>::size()) } else { None };
303 let mut subresult = reader.subresult(size)?;307 let mut subresult = reader.subresult(size)?;
304 Ok((308 Ok((
305 $(<$ident>::abi_read(&mut subresult)?,)+309 $({
310 let value = <$ident>::abi_read(&mut subresult)?;
311 if !is_dynamic {subresult.seek(<$ident as AbiType>::size())};
312 value
313 },)+
306 ))314 ))
307 }315 }
308 }316 }
modifiedcrates/evm-coder/src/abi/mod.rsdiffbeforeafterboth
75 buf: &[u8],75 buf: &[u8],
76 offset: usize,76 offset: usize,
77 pad_start: usize,77 pad_start: usize,
78 pad_size: usize,78 pad_end: usize,
79 block_start: usize,79 block_start: usize,
80 block_size: usize,80 block_end: usize,
81 ) -> Result<[u8; S]> {81 ) -> Result<[u8; S]> {
82 if buf.len() - offset < ABI_ALIGNMENT {82 if buf.len() - offset < ABI_ALIGNMENT {
83 return Err(Error::Error(ExitError::OutOfOffset));83 return Err(Error::Error(ExitError::OutOfOffset));
84 }84 }
85 let mut block = [0; S];85 let mut block = [0; S];
86 let is_pad_zeroed = buf[pad_start..pad_size].iter().all(|&v| v == 0);86 let is_pad_zeroed = buf[pad_start..pad_end].iter().all(|&v| v == 0);
87 if !is_pad_zeroed {87 if !is_pad_zeroed {
88 return Err(Error::Error(ExitError::InvalidRange));88 return Err(Error::Error(ExitError::InvalidRange));
89 }89 }
90 block.copy_from_slice(&buf[block_start..block_size]);90 block.copy_from_slice(&buf[block_start..block_end]);
91 Ok(block)91 Ok(block)
92 }92 }
9393
190 let subresult_offset = self.subresult_offset;190 let subresult_offset = self.subresult_offset;
191 let offset = if let Some(size) = size {191 let offset = if let Some(size) = size {
192 self.offset += size;192 self.offset += size;
193 self.subresult_offset += size;
194 0193 0
195 } else {194 } else {
196 self.uint32()? as usize195 self.uint32()? as usize
208 })207 })
209 }208 }
209
210 /// Notify about readed data portion.
211 pub fn seek(&mut self, size: usize) {
212 self.subresult_offset += size;
213 }
210214
211 /// Is this parser reached end of buffer?215 /// Is this parser reached end of buffer?
212 pub fn is_finished(&self) -> bool {216 pub fn is_finished(&self) -> bool {
modifiedcrates/evm-coder/src/abi/test.rsdiffbeforeafterboth
136 );136 );
137}137}
138
139#[test]
140fn encode_decode_vec_tuple_uint8_uint8() {
141 test_impl::<Vec<(u8, u8)>>(
142 0xdeadbeef,
143 vec![(0x0A, 0x0B), (0x0C, 0x0D), (0x0E, 0x0F)],
144 &hex!(
145 "
146 deadbeef
147 0000000000000000000000000000000000000000000000000000000000000020
148 0000000000000000000000000000000000000000000000000000000000000003
149 000000000000000000000000000000000000000000000000000000000000000a
150 000000000000000000000000000000000000000000000000000000000000000b
151 000000000000000000000000000000000000000000000000000000000000000c
152 000000000000000000000000000000000000000000000000000000000000000d
153 000000000000000000000000000000000000000000000000000000000000000e
154 000000000000000000000000000000000000000000000000000000000000000f
155 "
156 ),
157 );
158}
138159
139#[test]160#[test]
140fn encode_decode_vec_tuple_uint256_string() {161fn encode_decode_vec_tuple_uint256_string() {
333 );354 );
334}355}
356
357#[test]
358// #[ignore = "reason"]
359fn encode_decode_tuple0_tuple1_uint8_tuple1_string_bytes_tuple1_uint8_bytes() {
360 let int = 0xff;
361 let by = bytes(vec![0x11, 0x22, 0x33]);
362 let string = "some string".to_string();
363
364 test_impl::<((u8,), (String, bytes), (u8, bytes))>(
365 0xdeadbeef,
366 ((int,), (string.clone(), by.clone()), (int, by)),
367 &hex!(
368 "
369 deadbeef
370 0000000000000000000000000000000000000000000000000000000000000020
371 00000000000000000000000000000000000000000000000000000000000000ff
372 0000000000000000000000000000000000000000000000000000000000000060
373 0000000000000000000000000000000000000000000000000000000000000120
374 0000000000000000000000000000000000000000000000000000000000000040
375 0000000000000000000000000000000000000000000000000000000000000080
376 000000000000000000000000000000000000000000000000000000000000000b
377 736f6d6520737472696e67000000000000000000000000000000000000000000
378 0000000000000000000000000000000000000000000000000000000000000003
379 1122330000000000000000000000000000000000000000000000000000000000
380 00000000000000000000000000000000000000000000000000000000000000ff
381 0000000000000000000000000000000000000000000000000000000000000040
382 0000000000000000000000000000000000000000000000000000000000000003
383 1122330000000000000000000000000000000000000000000000000000000000
384 "
385 ),
386 );
387}
388
389#[test]
390fn encode_decode_tuple0_tuple1_uint8_tuple1_uint8_uint8_tuple1_uint8_uint8() {
391 test_impl::<((u8,), (u8, u8), (u8, u8))>(
392 0xdeadbeef,
393 ((43,), (44, 45), (46, 47)),
394 &hex!(
395 "
396 deadbeef
397 000000000000000000000000000000000000000000000000000000000000002b
398 000000000000000000000000000000000000000000000000000000000000002c
399 000000000000000000000000000000000000000000000000000000000000002d
400 000000000000000000000000000000000000000000000000000000000000002e
401 000000000000000000000000000000000000000000000000000000000000002f
402 "
403 ),
404 );
405}
406
407#[test]
408fn encode_decode_tuple0_tuple1_uint8_tuple1_uint8() {
409 test_impl::<((u8,), (u8,))>(
410 0xdeadbeef,
411 ((43,), (44,)),
412 &hex!(
413 "
414 deadbeef
415 000000000000000000000000000000000000000000000000000000000000002b
416 000000000000000000000000000000000000000000000000000000000000002c
417 "
418 ),
419 );
420}
421
422#[test]
423fn encode_decode_tuple0_tuple1_uint8_uint8() {
424 test_impl::<((u8, u8),)>(
425 0xdeadbeef,
426 ((43, 44),),
427 &hex!(
428 "
429 deadbeef
430 000000000000000000000000000000000000000000000000000000000000002b
431 000000000000000000000000000000000000000000000000000000000000002c
432 "
433 ),
434 );
435}
436
437#[test]
438fn encode_decode_tuple_uint8_uint8() {
439 test_impl::<(u8, u8)>(
440 0xdeadbeef,
441 (43, 44),
442 &hex!(
443 "
444 deadbeef
445 000000000000000000000000000000000000000000000000000000000000002b
446 000000000000000000000000000000000000000000000000000000000000002c
447 "
448 ),
449 );
450}
451
452#[test]
453fn encode_decode_tuple0_tuple1_string() {
454 test_impl::<((String,),)>(
455 0xdeadbeef,
456 (("some string".to_string(),),),
457 &hex!(
458 "
459 deadbeef
460 0000000000000000000000000000000000000000000000000000000000000020
461 0000000000000000000000000000000000000000000000000000000000000020
462 0000000000000000000000000000000000000000000000000000000000000020
463 000000000000000000000000000000000000000000000000000000000000000b
464 736f6d6520737472696e67000000000000000000000000000000000000000000
465 "
466 ),
467 );
468}
469
470#[test]
471fn encode_decode_tuple0_tuple1_uint8_string() {
472 test_impl::<((u8, String),)>(
473 0xdeadbeef,
474 ((0xff, "some string".to_string()),),
475 &hex!(
476 "
477 deadbeef
478 0000000000000000000000000000000000000000000000000000000000000020
479 0000000000000000000000000000000000000000000000000000000000000020
480 00000000000000000000000000000000000000000000000000000000000000ff
481 0000000000000000000000000000000000000000000000000000000000000040
482 000000000000000000000000000000000000000000000000000000000000000b
483 736f6d6520737472696e67000000000000000000000000000000000000000000
484 "
485 ),
486 );
487}
488
489#[test]
490fn encode_decode_tuple0_tuple1_string_bytes() {
491 test_impl::<((String, bytes),)>(
492 0xdeadbeef,
493 (("some string".to_string(), bytes(vec![1, 2, 3])),),
494 &hex!(
495 "
496 deadbeef
497 0000000000000000000000000000000000000000000000000000000000000020
498 0000000000000000000000000000000000000000000000000000000000000020
499 0000000000000000000000000000000000000000000000000000000000000040
500 0000000000000000000000000000000000000000000000000000000000000080
501 000000000000000000000000000000000000000000000000000000000000000b
502 736f6d6520737472696e67000000000000000000000000000000000000000000
503 0000000000000000000000000000000000000000000000000000000000000003
504 0102030000000000000000000000000000000000000000000000000000000000
505 "
506 ),
507 );
508}
509
510#[test]
511fn encode_decode_tuple0_tuple1_uint8_tuple1_string() {
512 test_impl::<((u8,), (String,))>(
513 0xdeadbeef,
514 ((0xff,), ("some string".to_string(),)),
515 &hex!(
516 "
517 deadbeef
518 0000000000000000000000000000000000000000000000000000000000000020
519 00000000000000000000000000000000000000000000000000000000000000ff
520 0000000000000000000000000000000000000000000000000000000000000040
521 0000000000000000000000000000000000000000000000000000000000000020
522 000000000000000000000000000000000000000000000000000000000000000b
523 736f6d6520737472696e67000000000000000000000000000000000000000000
524 "
525 ),
526 );
527}
335528
modifiedcrates/evm-coder/tests/abi_derive_generation.rsdiffbeforeafterboth
1use evm_coder_procedural::AbiCoder;1use evm_coder_procedural::AbiCoder;
2use evm_coder::{2use evm_coder::{
3 types::*,3 types::*,
4 abi::{AbiType, AbiRead, AbiWrite},4 abi::{AbiType, AbiRead, AbiWrite, AbiReader, AbiWriter},
5};5};
66
7// TODO: move to build_failed tests7// TODO: move to build_failed tests
406 );406 );
407}407}
408
409const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;
408410
409fn test_impl<TypeStruct, TupleStruct, Tuple>(411fn test_impl<Tuple, TupleStruct, TypeStruct>(
410 type_struct_data: TypeStruct,412 tuple_data: Tuple,
411 tuple_struct_data: TupleStruct,413 tuple_struct_data: TupleStruct,
412 tuple_data: Tuple,414 type_struct_data: TypeStruct,
413) where415) where
414 TypeStruct: AbiWrite + AbiRead + std::cmp::PartialEq + std::fmt::Debug,416 TypeStruct: AbiWrite + AbiRead + std::cmp::PartialEq + std::fmt::Debug,
417 TupleStruct: AbiWrite + AbiRead + std::cmp::PartialEq + std::fmt::Debug,
415 Tuple: AbiWrite + AbiRead + std::cmp::PartialEq + std::fmt::Debug,418 Tuple: AbiWrite + AbiRead + std::cmp::PartialEq + std::fmt::Debug,
416{419{
420 let encoded_type_struct = test_abi_write_impl(&type_struct_data);
421 let encoded_tuple_struct = test_abi_write_impl(&tuple_struct_data);
422 let encoded_tuple = test_abi_write_impl(&tuple_data);
423
417 use evm_coder::abi::{AbiReader, AbiWriter};424 similar_asserts::assert_eq!(encoded_tuple, encoded_type_struct);
418 const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;425 similar_asserts::assert_eq!(encoded_tuple, encoded_tuple_struct);
419426
427 // dbg!(&encoded_tuple);
428 // dbg!(&encoded_tuple_struct);
429 // dbg!(&encoded_type_struct);
430
431 {
420 let mut writer = AbiWriter::new_call(FUNCTION_IDENTIFIER);432 let (_, mut decoder) = AbiReader::new_call(&encoded_tuple).unwrap();
421 tuple_data.abi_write(&mut writer);433 let restored_struct_data = <TypeStruct>::abi_read(&mut decoder).unwrap();
434 assert_eq!(restored_struct_data, type_struct_data);
435 }
436 {
422 let encoded_tuple = writer.finish();437 let (_, mut decoder) = AbiReader::new_call(&encoded_tuple).unwrap();
423438 let restored_struct_data = <TupleStruct>::abi_read(&mut decoder).unwrap();
439 assert_eq!(restored_struct_data, tuple_struct_data);
440 }
441
442 {
424 let mut writer = AbiWriter::new_call(FUNCTION_IDENTIFIER);443 let (_, mut decoder) = AbiReader::new_call(&encoded_type_struct).unwrap();
425 type_struct_data.abi_write(&mut writer);444 let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();
445 assert_eq!(restored_tuple_data, tuple_data);
446 }
447 {
426 let encoded_struct = writer.finish();448 let (_, mut decoder) = AbiReader::new_call(&encoded_tuple_struct).unwrap();
427449 let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();
428 similar_asserts::assert_eq!(encoded_tuple, encoded_struct);450 assert_eq!(restored_tuple_data, tuple_data);
429451 }
430 // let (_, mut decoder) = AbiReader::new_call(&encoded_tuple).unwrap();
431 // let restored_struct_data = <TypeStruct>::abi_read(&mut decoder).unwrap();
432 // assert_eq!(restored_struct_data, type_struct_data);
433
434 // let (_, mut decoder) = AbiReader::new_call(&encoded_struct).unwrap();
435 // let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();
436 // assert_eq!(restored_tuple_data, tuple_data);
437}452}
453
454fn test_abi_write_impl<A>(data: &A) -> Vec<u8>
455where
456 A: AbiWrite + AbiRead + std::cmp::PartialEq + std::fmt::Debug,
457{
458 let mut writer = AbiWriter::new_call(FUNCTION_IDENTIFIER);
459 data.abi_write(&mut writer);
460 let encoded_tuple = writer.finish();
461 encoded_tuple
462}
438463
439#[test]464#[test]
440fn codec_struct_1_simple() {465fn codec_struct_1_simple() {
441 let _a = 0xff;466 let _a = 0xff;
442 test_impl::<TypeStruct1SimpleParam, TupleStruct1SimpleParam, (uint8,)>(467 test_impl::<(uint8,), TupleStruct1SimpleParam, TypeStruct1SimpleParam>(
443 TypeStruct1SimpleParam { _a },468 (_a,),
444 TupleStruct1SimpleParam(_a),469 TupleStruct1SimpleParam(_a),
445 (_a,),470 TypeStruct1SimpleParam { _a },
446 );471 );
447}472}
448473
449#[test]474#[test]
450fn codec_struct_1_dynamic() {475fn codec_struct_1_dynamic() {
451 let _a: String = "some string".into();476 let _a: String = "some string".into();
452 test_impl::<TypeStruct1DynamicParam, TupleStruct1DynamicParam, (String,)>(477 test_impl::<(String,), TupleStruct1DynamicParam, TypeStruct1DynamicParam>(
453 TypeStruct1DynamicParam { _a: _a.clone() },478 (_a.clone(),),
454 TupleStruct1DynamicParam(_a.clone()),479 TupleStruct1DynamicParam(_a.clone()),
455 (_a,),480 TypeStruct1DynamicParam { _a },
456 );481 );
457}482}
483
484#[test]
485fn codec_struct_1_derived_simple() {
486 let _a: u8 = 0xff;
487 test_impl::<((u8,),), TupleStruct1DerivedSimpleParam, TypeStruct1DerivedSimpleParam>(
488 ((_a,),),
489 TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam(_a)),
490 TypeStruct1DerivedSimpleParam {
491 _a: TypeStruct1SimpleParam { _a },
492 },
493 );
494}
495
496#[test]
497fn codec_struct_1_derived_dynamic() {
498 let _a: String = "some string".into();
499 test_impl::<((String,),), TupleStruct1DerivedDynamicParam, TypeStruct1DerivedDynamicParam>(
500 ((_a.clone(),),),
501 TupleStruct1DerivedDynamicParam(TupleStruct1DynamicParam(_a.clone())),
502 TypeStruct1DerivedDynamicParam {
503 _a: TypeStruct1DynamicParam { _a },
504 },
505 );
506}
507
508#[test]
509fn codec_struct_2_simple() {
510 let _a = 0xff;
511 let _b = 0xbeefbaba;
512 test_impl::<(u8, u32), TupleStruct2SimpleParam, TypeStruct2SimpleParam>(
513 (_a, _b),
514 TupleStruct2SimpleParam(_a, _b),
515 TypeStruct2SimpleParam { _a, _b },
516 );
517}
458518
459#[test]519#[test]
460fn codec_struct_2_dynamic() {520fn codec_struct_2_dynamic() {
461 let _a: String = "some string".into();521 let _a: String = "some string".into();
462 let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);522 let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);
463 test_impl::<TypeStruct2DynamicParam, TupleStruct2DynamicParam, (String, bytes)>(523 test_impl::<(String, bytes), TupleStruct2DynamicParam, TypeStruct2DynamicParam>(
464 TypeStruct2DynamicParam {
465 _a: _a.clone(),524 (_a.clone(), _b.clone()),
466 _b: _b.clone(),
467 },
468 TupleStruct2DynamicParam(_a.clone(), _b.clone()),525 TupleStruct2DynamicParam(_a.clone(), _b.clone()),
469 (_a, _b),526 TypeStruct2DynamicParam { _a, _b },
470 );527 );
471}528}
529
530#[test]
531fn codec_struct_2_mixed() {
532 let _a: u8 = 0xff;
533 let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);
534 test_impl::<(u8, bytes), TupleStruct2MixedParam, TypeStruct2MixedParam>(
535 (_a.clone(), _b.clone()),
536 TupleStruct2MixedParam(_a.clone(), _b.clone()),
537 TypeStruct2MixedParam { _a, _b },
538 );
539}
540
541#[test]
542fn codec_struct_2_derived_simple() {
543 let _a = 0xff;
544 let _b = 0xbeefbaba;
545 test_impl::<((u8,), (u8, u32)), TupleStruct2DerivedSimpleParam, TypeStruct2DerivedSimpleParam>(
546 ((_a,), (_a, _b)),
547 TupleStruct2DerivedSimpleParam(
548 TupleStruct1SimpleParam(_a),
549 TupleStruct2SimpleParam(_a, _b),
550 ),
551 TypeStruct2DerivedSimpleParam {
552 _a: TypeStruct1SimpleParam { _a },
553 _b: TypeStruct2SimpleParam { _a, _b },
554 },
555 );
556}
557
558#[test]
559fn codec_struct_2_derived_dynamic() {
560 let _a = "some string".to_string();
561 let _b = bytes(vec![0x11, 0x22, 0x33]);
562 test_impl::<
563 ((String,), (String, bytes)),
564 TupleStruct2DerivedDynamicParam,
565 TypeStruct2DerivedDynamicParam,
566 >(
567 ((_a.clone(),), (_a.clone(), _b.clone())),
568 TupleStruct2DerivedDynamicParam(
569 TupleStruct1DynamicParam(_a.clone()),
570 TupleStruct2DynamicParam(_a.clone(), _b.clone()),
571 ),
572 TypeStruct2DerivedDynamicParam {
573 _a: TypeStruct1DynamicParam { _a: _a.clone() },
574 _b: TypeStruct2DynamicParam { _a, _b },
575 },
576 );
577}
578
579#[test]
580fn codec_struct_3_derived_mixed() {
581 let int = 0xff;
582 let by = bytes(vec![0x11, 0x22, 0x33]);
583 let string = "some string".to_string();
584 test_impl::<
585 ((u8,), (String, bytes), (u8, bytes)),
586 TupleStruct3DerivedMixedParam,
587 TypeStruct3DerivedMixedParam,
588 >(
589 ((int,), (string.clone(), by.clone()), (int, by.clone())),
590 TupleStruct3DerivedMixedParam(
591 TupleStruct1SimpleParam(int),
592 TupleStruct2DynamicParam(string.clone(), by.clone()),
593 TupleStruct2MixedParam(int, by.clone()),
594 ),
595 TypeStruct3DerivedMixedParam {
596 _a: TypeStruct1SimpleParam { _a: int },
597 _b: TypeStruct2DynamicParam {
598 _a: string.clone(),
599 _b: by.clone(),
600 },
601 _c: TypeStruct2MixedParam { _a: int, _b: by },
602 },
603 );
604}
472605