diff --git a/framework/base/src/types/interaction/contract_call_legacy/contract_deploy.rs b/framework/base/src/types/interaction/contract_call_legacy/contract_deploy.rs index 6b19010e3d..8b12548b30 100644 --- a/framework/base/src/types/interaction/contract_call_legacy/contract_deploy.rs +++ b/framework/base/src/types/interaction/contract_call_legacy/contract_deploy.rs @@ -9,7 +9,7 @@ use crate::{ api::{BlockchainApiImpl, CallTypeApi}, contract_base::{ExitCodecErrorHandler, SendRawWrapper}, err_msg, - io::{ArgErrorHandler, ArgId, ManagedResultArgLoader}, + io::{ArgErrorHandler, ArgId}, types::{ BigUint, CodeMetadata, ManagedAddress, ManagedArgBuffer, ManagedBuffer, ManagedOption, ManagedVec, @@ -112,7 +112,7 @@ where where RequestedResult: TopDecodeMulti + TypeAbiFrom, { - let mut loader = ManagedResultArgLoader::new(raw_result); + let mut loader = raw_result.into_iter(); let arg_id = ArgId::from(&b"init result"[..]); let h = ArgErrorHandler::::from(arg_id); RequestedResult::multi_decode_or_handle_err(&mut loader, h).unwrap_infallible() diff --git a/framework/base/src/types/interaction/tx_exec.rs b/framework/base/src/types/interaction/tx_exec.rs index 0c200df330..6f4ffc40d3 100644 --- a/framework/base/src/types/interaction/tx_exec.rs +++ b/framework/base/src/types/interaction/tx_exec.rs @@ -15,7 +15,7 @@ use unwrap_infallible::UnwrapInfallible; use crate::{ api::CallTypeApi, - io::{ArgErrorHandler, ArgId, ManagedResultArgLoader}, + io::{ArgErrorHandler, ArgId}, types::{ManagedBuffer, ManagedVec}, }; use multiversx_sc_codec::TopDecodeMulti; @@ -30,7 +30,7 @@ where SA: CallTypeApi + 'static, RequestedResult: TopDecodeMulti, { - let mut loader = ManagedResultArgLoader::new(raw_result); + let mut loader = raw_result.into_iter(); let arg_id = ArgId::from(&b"sync result"[..]); let h: ArgErrorHandler = ArgErrorHandler::::from(arg_id); RequestedResult::multi_decode_or_handle_err(&mut loader, h).unwrap_infallible() diff --git a/framework/base/src/types/managed/multi_value/multi_value_encoded_iter.rs b/framework/base/src/types/managed/multi_value/multi_value_encoded_iter.rs index 4b8db58ffb..670586fbf6 100644 --- a/framework/base/src/types/managed/multi_value/multi_value_encoded_iter.rs +++ b/framework/base/src/types/managed/multi_value/multi_value_encoded_iter.rs @@ -4,10 +4,10 @@ use unwrap_infallible::UnwrapInfallible; use crate::codec::{TopDecodeMulti, TopDecodeMultiInput}; -use crate::types::{ManagedBuffer, ManagedVec}; +use crate::types::{ManagedBuffer, ManagedVec, ManagedVecOwnedIterator}; use crate::{ api::{ErrorApi, ManagedTypeApi}, - io::{ArgErrorHandler, ArgId, ManagedResultArgLoader}, + io::{ArgErrorHandler, ArgId}, }; /// Iterator for `MultiValueEncoded` and `MultiValueEncodedCounted`. @@ -18,7 +18,7 @@ where M: ManagedTypeApi + ErrorApi, T: TopDecodeMulti, { - data_loader: ManagedResultArgLoader, + data_loader: ManagedVecOwnedIterator>, _phantom: PhantomData, } @@ -29,7 +29,7 @@ where { pub(crate) fn new(raw_buffers: ManagedVec>) -> Self { MultiValueEncodedIterator { - data_loader: ManagedResultArgLoader::new(raw_buffers), + data_loader: raw_buffers.into_iter(), _phantom: PhantomData, } } @@ -43,14 +43,13 @@ where type Item = T; fn next(&mut self) -> Option { - if self.data_loader.has_next() { - let arg_id = ArgId::from(&b"var args"[..]); - let h = ArgErrorHandler::::from(arg_id); - let result = - T::multi_decode_or_handle_err(&mut self.data_loader, h).unwrap_infallible(); - Some(result) - } else { - None + if !self.data_loader.has_next() { + return None; } + + let arg_id = ArgId::from(&b"var args"[..]); + let h = ArgErrorHandler::::from(arg_id); + let result = T::multi_decode_or_handle_err(&mut self.data_loader, h).unwrap_infallible(); + Some(result) } } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_iter_owned.rs b/framework/base/src/types/managed/wrapped/managed_vec_iter_owned.rs index 055b4b4a11..f4712e7464 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_iter_owned.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_iter_owned.rs @@ -1,4 +1,9 @@ -use crate::{api::ManagedTypeApi, types::ManagedType}; +use multiversx_sc_codec::{DecodeError, DecodeErrorHandler, TopDecodeMultiInput}; + +use crate::{ + api::{ErrorApi, ManagedTypeApi}, + types::{ManagedBuffer, ManagedType}, +}; use super::{ManagedVec, ManagedVecItem, ManagedVecPayloadIterator}; @@ -34,6 +39,10 @@ where } } } + + pub(crate) fn iter_is_empty(&self) -> bool { + self.payload_iter.iter_is_empty() + } } impl Iterator for ManagedVecOwnedIterator @@ -70,3 +79,25 @@ where Some(T::read_from_payload(&payload)) } } + +impl TopDecodeMultiInput for ManagedVecOwnedIterator> +where + A: ManagedTypeApi + ErrorApi, +{ + type ValueInput = ManagedBuffer; + + fn has_next(&self) -> bool { + !self.iter_is_empty() + } + + fn next_value_input(&mut self, h: H) -> Result + where + H: DecodeErrorHandler, + { + if let Some(buffer) = self.next() { + Ok(buffer) + } else { + Err(h.handle_error(DecodeError::MULTI_TOO_FEW_ARGS)) + } + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_vec_iter_payload.rs b/framework/base/src/types/managed/wrapped/managed_vec_iter_payload.rs index 44293133d2..28fd6e3943 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_iter_payload.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_iter_payload.rs @@ -40,6 +40,15 @@ where _phantom: PhantomData, } } + + pub(crate) fn remaining(&self) -> usize { + (self.byte_end - self.byte_start) / P::payload_size() + } + + /// TODO: can be replaced with ExactSizeIterator::is_empty once it's stabilized + pub(crate) fn iter_is_empty(&self) -> bool { + self.byte_start >= self.byte_end + } } impl Iterator for ManagedVecPayloadIterator @@ -50,10 +59,10 @@ where type Item = P; fn next(&mut self) -> Option

{ - let next_byte_start = self.byte_start + P::payload_size(); - if next_byte_start > self.byte_end { + if self.iter_is_empty() { return None; } + let next_byte_start = self.byte_start + P::payload_size(); let mut payload = P::new_buffer(); let _ = M::managed_type_impl().mb_load_slice( @@ -67,8 +76,7 @@ where } fn size_hint(&self) -> (usize, Option) { - let size = P::payload_size(); - let remaining = (self.byte_end - self.byte_start) / size; + let remaining = self.remaining(); (remaining, Some(remaining)) } } @@ -78,6 +86,9 @@ where M: ManagedTypeApi, P: ManagedVecItemPayload, { + fn len(&self) -> usize { + self.remaining() + } } impl DoubleEndedIterator for ManagedVecPayloadIterator @@ -86,7 +97,7 @@ where P: ManagedVecItemPayload, { fn next_back(&mut self) -> Option { - if self.byte_start + P::payload_size() > self.byte_end { + if self.iter_is_empty() { return None; } self.byte_end -= P::payload_size(); diff --git a/framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs b/framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs index b57a16d3d7..7305462b1c 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs @@ -1,6 +1,11 @@ use core::marker::PhantomData; -use crate::{api::ManagedTypeApi, types::ManagedType}; +use multiversx_sc_codec::{DecodeError, DecodeErrorHandler, TopDecodeMultiInput}; + +use crate::{ + api::{ErrorApi, ManagedTypeApi}, + types::{ManagedBuffer, ManagedType}, +}; use super::{ManagedVec, ManagedVecItem, ManagedVecPayloadIterator}; @@ -38,6 +43,10 @@ where } } } + + pub(crate) fn iter_is_empty(&self) -> bool { + self.payload_iter.iter_is_empty() + } } impl<'a, M, T> Iterator for ManagedVecRefIterator<'a, M, T> @@ -89,3 +98,25 @@ where } } } + +impl<'a, A> TopDecodeMultiInput for ManagedVecRefIterator<'a, A, ManagedBuffer> +where + A: ManagedTypeApi + ErrorApi, +{ + type ValueInput = ManagedBuffer; + + fn has_next(&self) -> bool { + !self.iter_is_empty() + } + + fn next_value_input(&mut self, h: H) -> Result + where + H: DecodeErrorHandler, + { + if let Some(buffer) = self.next() { + Ok(buffer.clone()) + } else { + Err(h.handle_error(DecodeError::MULTI_TOO_FEW_ARGS)) + } + } +}