Skip to content

Commit

Permalink
refactor: ManagedResultArgLoader replaced with ManagedVec iterators
Browse files Browse the repository at this point in the history
  • Loading branch information
andrei-marinica committed Dec 11, 2024
1 parent de3b6df commit 81f28d5
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -112,7 +112,7 @@ where
where
RequestedResult: TopDecodeMulti + TypeAbiFrom<OriginalResult>,
{
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::<SA>::from(arg_id);
RequestedResult::multi_decode_or_handle_err(&mut loader, h).unwrap_infallible()
Expand Down
4 changes: 2 additions & 2 deletions framework/base/src/types/interaction/tx_exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<SA> = ArgErrorHandler::<SA>::from(arg_id);
RequestedResult::multi_decode_or_handle_err(&mut loader, h).unwrap_infallible()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand All @@ -18,7 +18,7 @@ where
M: ManagedTypeApi + ErrorApi,
T: TopDecodeMulti,
{
data_loader: ManagedResultArgLoader<M>,
data_loader: ManagedVecOwnedIterator<M, ManagedBuffer<M>>,
_phantom: PhantomData<T>,
}

Expand All @@ -29,7 +29,7 @@ where
{
pub(crate) fn new(raw_buffers: ManagedVec<M, ManagedBuffer<M>>) -> Self {
MultiValueEncodedIterator {
data_loader: ManagedResultArgLoader::new(raw_buffers),
data_loader: raw_buffers.into_iter(),
_phantom: PhantomData,
}
}
Expand All @@ -43,14 +43,13 @@ where
type Item = T;

fn next(&mut self) -> Option<T> {
if self.data_loader.has_next() {
let arg_id = ArgId::from(&b"var args"[..]);
let h = ArgErrorHandler::<M>::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::<M>::from(arg_id);
let result = T::multi_decode_or_handle_err(&mut self.data_loader, h).unwrap_infallible();
Some(result)
}
}
Original file line number Diff line number Diff line change
@@ -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};

Expand Down Expand Up @@ -34,6 +39,10 @@ where
}
}
}

pub(crate) fn iter_is_empty(&self) -> bool {
self.payload_iter.iter_is_empty()
}
}

impl<M, T> Iterator for ManagedVecOwnedIterator<M, T>
Expand Down Expand Up @@ -70,3 +79,25 @@ where
Some(T::read_from_payload(&payload))
}
}

impl<A> TopDecodeMultiInput for ManagedVecOwnedIterator<A, ManagedBuffer<A>>
where
A: ManagedTypeApi + ErrorApi,
{
type ValueInput = ManagedBuffer<A>;

fn has_next(&self) -> bool {
!self.iter_is_empty()
}

fn next_value_input<H>(&mut self, h: H) -> Result<Self::ValueInput, H::HandledErr>
where
H: DecodeErrorHandler,
{
if let Some(buffer) = self.next() {
Ok(buffer)
} else {
Err(h.handle_error(DecodeError::MULTI_TOO_FEW_ARGS))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<M, P> Iterator for ManagedVecPayloadIterator<M, P>
Expand All @@ -50,10 +59,10 @@ where
type Item = P;

fn next(&mut self) -> Option<P> {
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(
Expand All @@ -67,8 +76,7 @@ where
}

fn size_hint(&self) -> (usize, Option<usize>) {
let size = P::payload_size();
let remaining = (self.byte_end - self.byte_start) / size;
let remaining = self.remaining();
(remaining, Some(remaining))
}
}
Expand All @@ -78,6 +86,9 @@ where
M: ManagedTypeApi,
P: ManagedVecItemPayload,
{
fn len(&self) -> usize {
self.remaining()
}
}

impl<M, P> DoubleEndedIterator for ManagedVecPayloadIterator<M, P>
Expand All @@ -86,7 +97,7 @@ where
P: ManagedVecItemPayload,
{
fn next_back(&mut self) -> Option<Self::Item> {
if self.byte_start + P::payload_size() > self.byte_end {
if self.iter_is_empty() {
return None;
}
self.byte_end -= P::payload_size();
Expand Down
33 changes: 32 additions & 1 deletion framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -89,3 +98,25 @@ where
}
}
}

impl<'a, A> TopDecodeMultiInput for ManagedVecRefIterator<'a, A, ManagedBuffer<A>>

Check warning on line 102 in framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs

View workflow job for this annotation

GitHub Actions / clippy

[clippy] framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs#L102

warning: the following explicit lifetimes could be elided: 'a --> framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs:102:6 | 102 | impl<'a, A> TopDecodeMultiInput for ManagedVecRefIterator<'a, A, ManagedBuffer<A>> | ^^ ^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes = note: `#[warn(clippy::needless_lifetimes)]` on by default help: elide the lifetimes | 102 - impl<'a, A> TopDecodeMultiInput for ManagedVecRefIterator<'a, A, ManagedBuffer<A>> 102 + impl<A> TopDecodeMultiInput for ManagedVecRefIterator<'_, A, ManagedBuffer<A>> |
Raw output
framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs:102:6:w:warning: the following explicit lifetimes could be elided: 'a
   --> framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs:102:6
    |
102 | impl<'a, A> TopDecodeMultiInput for ManagedVecRefIterator<'a, A, ManagedBuffer<A>>
    |      ^^                                                   ^^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    = note: `#[warn(clippy::needless_lifetimes)]` on by default
help: elide the lifetimes
    |
102 - impl<'a, A> TopDecodeMultiInput for ManagedVecRefIterator<'a, A, ManagedBuffer<A>>
102 + impl<A> TopDecodeMultiInput for ManagedVecRefIterator<'_, A, ManagedBuffer<A>>
    |


__END__

Check warning on line 102 in framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs

View workflow job for this annotation

GitHub Actions / clippy

[clippy] framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs#L102

warning: the following explicit lifetimes could be elided: 'a --> framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs:102:6 | 102 | impl<'a, A> TopDecodeMultiInput for ManagedVecRefIterator<'a, A, ManagedBuffer<A>> | ^^ ^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes = note: `#[warn(clippy::needless_lifetimes)]` on by default help: elide the lifetimes | 102 - impl<'a, A> TopDecodeMultiInput for ManagedVecRefIterator<'a, A, ManagedBuffer<A>> 102 + impl<A> TopDecodeMultiInput for ManagedVecRefIterator<'_, A, ManagedBuffer<A>> |
Raw output
framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs:102:6:w:warning: the following explicit lifetimes could be elided: 'a
   --> framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs:102:6
    |
102 | impl<'a, A> TopDecodeMultiInput for ManagedVecRefIterator<'a, A, ManagedBuffer<A>>
    |      ^^                                                   ^^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    = note: `#[warn(clippy::needless_lifetimes)]` on by default
help: elide the lifetimes
    |
102 - impl<'a, A> TopDecodeMultiInput for ManagedVecRefIterator<'a, A, ManagedBuffer<A>>
102 + impl<A> TopDecodeMultiInput for ManagedVecRefIterator<'_, A, ManagedBuffer<A>>
    |


__END__
where
A: ManagedTypeApi + ErrorApi,
{
type ValueInput = ManagedBuffer<A>;

fn has_next(&self) -> bool {
!self.iter_is_empty()
}

fn next_value_input<H>(&mut self, h: H) -> Result<Self::ValueInput, H::HandledErr>
where
H: DecodeErrorHandler,
{
if let Some(buffer) = self.next() {
Ok(buffer.clone())
} else {
Err(h.handle_error(DecodeError::MULTI_TOO_FEW_ARGS))
}
}
}

0 comments on commit 81f28d5

Please sign in to comment.