From 3f45a2f101daafc310cf7ca60d20bc032aadca8e Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Sun, 27 Oct 2024 18:21:06 +0200 Subject: [PATCH 1/2] ManagedVec set takes owned item --- .../basic-features/src/managed_vec_features.rs | 2 +- .../tests/basic_features_managed_vec_test.rs | 2 +- .../base/src/types/managed/wrapped/managed_vec.rs | 2 +- .../base/src/types/managed/wrapped/managed_vec_ref.rs | 10 ++++++---- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/contracts/feature-tests/basic-features/src/managed_vec_features.rs b/contracts/feature-tests/basic-features/src/managed_vec_features.rs index 6f42d104be..3b0f9e505d 100644 --- a/contracts/feature-tests/basic-features/src/managed_vec_features.rs +++ b/contracts/feature-tests/basic-features/src/managed_vec_features.rs @@ -39,7 +39,7 @@ pub trait ManagedVecFeatures { &self, mv: ManagedVec, index: usize, - item: &BigUint, + item: BigUint, ) -> ManagedVec { let mut result = mv; if result.set(index, item).is_ok() { diff --git a/contracts/feature-tests/basic-features/tests/basic_features_managed_vec_test.rs b/contracts/feature-tests/basic-features/tests/basic_features_managed_vec_test.rs index fccc91e431..68965c5b60 100644 --- a/contracts/feature-tests/basic-features/tests/basic_features_managed_vec_test.rs +++ b/contracts/feature-tests/basic-features/tests/basic_features_managed_vec_test.rs @@ -44,5 +44,5 @@ fn test_managed_vec_set() { mv2.push(BigUint::from(1u32)); mv2.push(BigUint::from(5u32)); mv2.push(BigUint::from(3u32)); - assert_eq!(bf.managed_vec_set(mv1, 1, &BigUint::from(5u64)), mv2); + assert_eq!(bf.managed_vec_set(mv1, 1, BigUint::from(5u64)), mv2); } diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index e37dd872d5..25fc704711 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -190,7 +190,7 @@ where } } - pub fn set(&mut self, index: usize, item: &T) -> Result<(), InvalidSliceError> { + pub fn set(&mut self, index: usize, item: T) -> Result<(), InvalidSliceError> { let byte_index = index * T::payload_size(); item.to_byte_writer(|slice| self.buffer.set_slice(byte_index, slice)) } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_ref.rs b/framework/base/src/types/managed/wrapped/managed_vec_ref.rs index dc2b722fbd..b69a124668 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_ref.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_ref.rs @@ -4,6 +4,7 @@ use crate::{ }; use core::{ marker::PhantomData, + mem::ManuallyDrop, ops::{Deref, DerefMut}, }; @@ -16,7 +17,7 @@ where _phantom_t: PhantomData<&'a mut T>, // needed for the lifetime, even though T is present managed_vec_handle: M::ManagedBufferHandle, item_index: usize, - item: T, + item: ManuallyDrop, } impl<'a, M, T> ManagedVecRef<'a, M, T> @@ -37,7 +38,7 @@ where _phantom_t: PhantomData, managed_vec_handle, item_index, - item, + item: ManuallyDrop::new(item), } } } @@ -48,8 +49,9 @@ where T: ManagedVecItem, { fn drop(&mut self) { - let _ = Self::wrap_as_managed_vec(self.managed_vec_handle.clone()) - .set(self.item_index, &self.item); + let item = unsafe { ManuallyDrop::take(&mut self.item) }; + let _ = + Self::wrap_as_managed_vec(self.managed_vec_handle.clone()).set(self.item_index, item); } } From c9e88db7ea78a8f01ef832ee49d6509ed6800921 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Sun, 27 Oct 2024 18:55:17 +0200 Subject: [PATCH 2/2] ManagedVecItem into_byte_writer rename + consumes ownership --- .../esdt_token_payment_multi_value.rs | 4 +- .../managed/wrapped/esdt_token_payment.rs | 12 ++--- .../types/managed/wrapped/managed_option.rs | 4 +- .../src/types/managed/wrapped/managed_vec.rs | 6 +-- .../types/managed/wrapped/managed_vec_item.rs | 47 +++++++++++-------- .../derive/src/managed_vec_item_derive.rs | 6 +-- .../src/api/impl_vh/debug_handle_vh.rs | 4 +- .../derive_managed_vec_item_biguint_test.rs | 4 +- ...anaged_vec_item_esdt_token_payment_test.rs | 4 +- .../derive_managed_vec_item_simple_enum.rs | 4 +- .../derive_managed_vec_item_struct_1_test.rs | 2 +- .../derive_managed_vec_item_struct_2_test.rs | 2 +- 12 files changed, 54 insertions(+), 45 deletions(-) diff --git a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs index 7e7cd934a3..1ebc5d5fe7 100644 --- a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs +++ b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs @@ -57,8 +57,8 @@ impl ManagedVecItem for EsdtTokenPaymentMultiValue { } #[inline] - fn to_byte_writer R>(&self, writer: Writer) -> R { - self.obj.to_byte_writer(writer) + fn into_byte_writer R>(self, writer: Writer) -> R { + self.obj.into_byte_writer(writer) } } diff --git a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs index 5aedefb3d8..cf2ccf0ceb 100644 --- a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs @@ -164,11 +164,11 @@ where }) } -fn managed_vec_item_to_slice(arr: &mut [u8], index: &mut usize, item: &T) +fn managed_vec_item_to_slice(arr: &mut [u8], index: &mut usize, item: T) where T: ManagedVecItem, { - ManagedVecItem::to_byte_writer(item, |bytes| { + ManagedVecItem::into_byte_writer(item, |bytes| { let size = T::payload_size(); arr[*index..*index + size].copy_from_slice(bytes); *index += size; @@ -211,13 +211,13 @@ impl ManagedVecItem for EsdtTokenPayment { Self::from_byte_reader(reader) } - fn to_byte_writer R>(&self, mut writer: Writer) -> R { + fn into_byte_writer R>(self, mut writer: Writer) -> R { let mut arr: [u8; 16] = [0u8; 16]; let mut index = 0; - managed_vec_item_to_slice(&mut arr, &mut index, &self.token_identifier); - managed_vec_item_to_slice(&mut arr, &mut index, &self.token_nonce); - managed_vec_item_to_slice(&mut arr, &mut index, &self.amount); + managed_vec_item_to_slice(&mut arr, &mut index, self.token_identifier); + managed_vec_item_to_slice(&mut arr, &mut index, self.token_nonce); + managed_vec_item_to_slice(&mut arr, &mut index, self.amount); writer(&arr[..]) } diff --git a/framework/base/src/types/managed/wrapped/managed_option.rs b/framework/base/src/types/managed/wrapped/managed_option.rs index eb17ae81e4..e448ae8e88 100644 --- a/framework/base/src/types/managed/wrapped/managed_option.rs +++ b/framework/base/src/types/managed/wrapped/managed_option.rs @@ -210,8 +210,8 @@ where Self::from_byte_reader(reader) } - fn to_byte_writer R>(&self, writer: Writer) -> R { - ::to_byte_writer(&self.handle.clone(), writer) + fn into_byte_writer R>(self, writer: Writer) -> R { + ::into_byte_writer(self.handle, writer) } } diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index 25fc704711..3e25360ea4 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -192,7 +192,7 @@ where pub fn set(&mut self, index: usize, item: T) -> Result<(), InvalidSliceError> { let byte_index = index * T::payload_size(); - item.to_byte_writer(|slice| self.buffer.set_slice(byte_index, slice)) + item.into_byte_writer(|slice| self.buffer.set_slice(byte_index, slice)) } /// Returns a new `ManagedVec`, containing the [start_index, end_index) range of elements. @@ -205,7 +205,7 @@ where } pub fn push(&mut self, item: T) { - item.to_byte_writer(|bytes| { + item.into_byte_writer(|bytes| { self.buffer.append_bytes(bytes); }); } @@ -251,7 +251,7 @@ where } pub fn overwrite_with_single_item(&mut self, item: T) { - item.to_byte_writer(|bytes| { + item.into_byte_writer(|bytes| { self.buffer.overwrite(bytes); }); } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index 00cb212c18..8e7dc5512a 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -53,7 +53,16 @@ pub trait ManagedVecItem: 'static { reader: Reader, ) -> Self::Ref<'a>; - fn to_byte_writer R>(&self, writer: Writer) -> R; + /// Converts the object into bytes. + /// + /// The output is processed by the `writer` lambda. + /// The writer is provided by the caller. + /// The callee will use it to pass on the bytes. + /// + /// The method is used when instering (push, overwrite) into a ManagedVec. + /// + /// Note that a destructor should not be called at this moment, since the ManagedVec will take ownership of the item. + fn into_byte_writer R>(self, writer: Writer) -> R; } macro_rules! impl_int { @@ -73,7 +82,7 @@ macro_rules! impl_int { Self::from_byte_reader(reader) } - fn to_byte_writer R>(&self, mut writer: Writer) -> R { + fn into_byte_writer R>(self, mut writer: Writer) -> R { let bytes = self.to_be_bytes(); writer(&bytes) } @@ -104,8 +113,8 @@ impl ManagedVecItem for usize { Self::from_byte_reader(reader) } - fn to_byte_writer R>(&self, mut writer: Writer) -> R { - let bytes = (*self as u32).to_be_bytes(); + fn into_byte_writer R>(self, mut writer: Writer) -> R { + let bytes = (self as u32).to_be_bytes(); writer(&bytes) } } @@ -125,11 +134,11 @@ impl ManagedVecItem for bool { Self::from_byte_reader(reader) } - fn to_byte_writer R>(&self, writer: Writer) -> R { + fn into_byte_writer R>(self, writer: Writer) -> R { // true -> 1u8 // false -> 0u8 - let u8_value = u8::from(*self); - ::to_byte_writer(&u8_value, writer) + let u8_value = u8::from(self); + ::into_byte_writer(u8_value, writer) } } @@ -161,12 +170,12 @@ where Self::from_byte_reader(reader) } - fn to_byte_writer R>(&self, mut writer: Writer) -> R { + fn into_byte_writer R>(self, mut writer: Writer) -> R { let mut payload = Self::PAYLOAD::new_buffer(); let slice = payload.payload_slice_mut(); if let Some(t) = self { slice[0] = 1; - T::to_byte_writer(t, |bytes| { + T::into_byte_writer(t, |bytes| { slice[1..].copy_from_slice(bytes); }); } @@ -193,8 +202,8 @@ macro_rules! impl_managed_type { ManagedRef::wrap_handle(handle) } - fn to_byte_writer R>(&self, writer: Writer) -> R { - <$ty as ManagedType>::OwnHandle::to_byte_writer(&self.get_handle(), writer) + fn into_byte_writer R>(self, writer: Writer) -> R { + <$ty as ManagedType>::OwnHandle::into_byte_writer(self.get_handle(), writer) } } }; @@ -227,9 +236,9 @@ where ManagedRef::wrap_handle(handle) } - fn to_byte_writer R>(&self, writer: Writer) -> R { - <>::OwnHandle as ManagedVecItem>::to_byte_writer( - &self.get_handle(), + fn into_byte_writer R>(self, writer: Writer) -> R { + <>::OwnHandle as ManagedVecItem>::into_byte_writer( + self.get_handle(), writer, ) } @@ -256,8 +265,8 @@ where ManagedRef::wrap_handle(handle) } - fn to_byte_writer R>(&self, writer: Writer) -> R { - ::to_byte_writer(&self.get_handle(), writer) + fn into_byte_writer R>(self, writer: Writer) -> R { + ::into_byte_writer(self.get_handle(), writer) } } @@ -278,7 +287,7 @@ impl ManagedVecItem for EsdtTokenType { Self::from_byte_reader(reader) } - fn to_byte_writer R>(&self, mut writer: Writer) -> R { + fn into_byte_writer R>(self, mut writer: Writer) -> R { writer(&[self.as_u8()]) } } @@ -298,7 +307,7 @@ impl ManagedVecItem for EsdtLocalRole { Self::from_byte_reader(reader) } - fn to_byte_writer R>(&self, writer: Writer) -> R { - ::to_byte_writer(&self.as_u16(), writer) + fn into_byte_writer R>(self, writer: Writer) -> R { + ::into_byte_writer(self.as_u16(), writer) } } diff --git a/framework/derive/src/managed_vec_item_derive.rs b/framework/derive/src/managed_vec_item_derive.rs index 1755182f34..17c07f21a4 100644 --- a/framework/derive/src/managed_vec_item_derive.rs +++ b/framework/derive/src/managed_vec_item_derive.rs @@ -75,7 +75,7 @@ fn generate_to_byte_writer_snippets(fields: &syn::Fields) -> Vec::payload_size(); payload_slice[index .. next_index].copy_from_slice(bytes); index = next_index; @@ -137,7 +137,7 @@ fn enum_derive(data_enum: &syn::DataEnum, ast: &syn::DeriveInput) -> TokenStream Self::from_byte_reader(reader) } - fn to_byte_writer R>(&self, mut writer: Writer) -> R { + fn into_byte_writer R>(self, mut writer: Writer) -> R { let mut arr: [u8; 1] = [0u8; 1]; arr[0] = match self { #(#writer_match_arms)* @@ -180,7 +180,7 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token Self::from_byte_reader(reader) } - fn to_byte_writer R>(&self, mut writer: Writer) -> R { + fn into_byte_writer R>(self, mut writer: Writer) -> R { #payload_buffer_snippet let mut index = 0; diff --git a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs index 0623270758..99dc7c6e87 100644 --- a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs +++ b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs @@ -93,8 +93,8 @@ impl ManagedVecItem for DebugHandle { use_raw_handle(RawHandle::from_byte_reader(reader)) } - fn to_byte_writer R>(&self, writer: Writer) -> R { - RawHandle::to_byte_writer(&self.get_raw_handle(), writer) + fn into_byte_writer R>(self, writer: Writer) -> R { + RawHandle::into_byte_writer(self.get_raw_handle(), writer) } } diff --git a/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs b/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs index 9e0cfa8c74..6efd920acc 100644 --- a/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs @@ -45,8 +45,8 @@ fn managed_struct_to_bytes_writer() { let handle_bytes = s.big_uint.get_handle().to_be_bytes(); let expected = [0xff, 0xff, 0xff, handle_bytes[3], 0x00, 0x01, 0x23, 0x45]; - as multiversx_sc::types::ManagedVecItem>::to_byte_writer( - &s, + as multiversx_sc::types::ManagedVecItem>::into_byte_writer( + s, |bytes| { payload_slice.copy_from_slice(bytes); diff --git a/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs b/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs index fc7d95343e..1018747da3 100644 --- a/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs @@ -63,8 +63,8 @@ fn struct_to_bytes_writer() { handle3[1], handle3[2], handle3[3], handle4[0], handle4[1], handle4[2], handle4[3], ]; - as multiversx_sc::types::ManagedVecItem>::to_byte_writer( - &s, + as multiversx_sc::types::ManagedVecItem>::into_byte_writer( + s, |bytes| { payload_slice.copy_from_slice(bytes); diff --git a/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs b/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs index 1c139f5b84..46dcceed33 100644 --- a/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs +++ b/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs @@ -27,8 +27,8 @@ fn enum_static() { #[test] fn enum_to_bytes_writer() { - ::to_byte_writer( - &SimpleEnum::Variant1, + ::into_byte_writer( + SimpleEnum::Variant1, |bytes| { assert_eq!(bytes.len(), 1); assert_eq!(bytes[0], 0); diff --git a/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs b/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs index e5ee344e3c..e55e6d9140 100644 --- a/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs @@ -67,7 +67,7 @@ fn struct_1_to_bytes_writer() { let mut payload = ::PAYLOAD::new_buffer(); let payload_slice = payload.payload_slice_mut(); - ::to_byte_writer(&s, |bytes| { + ::into_byte_writer(s, |bytes| { payload_slice.copy_from_slice(bytes); assert_eq!( payload_slice, diff --git a/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs b/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs index 87fee5ed62..50bea73aac 100644 --- a/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs @@ -49,7 +49,7 @@ fn struct_to_bytes_writer() { /* arr */ 0x61, 0x11, 0x62, 0x22, ]; - ::to_byte_writer(&s, |bytes| { + ::into_byte_writer(s, |bytes| { assert_eq!(bytes, &expected_payload[..]); }); }