From c55974dd010f62391b9cf9053d0d29a58c6c0bce Mon Sep 17 00:00:00 2001 From: Ivan Kalinin Date: Tue, 14 Nov 2023 16:04:12 +0100 Subject: [PATCH] Add `FromAbiIter` trait --- src/abi/mod.rs | 3 ++- src/abi/traits.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index a2e419fa..602c2503 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -9,7 +9,8 @@ pub use self::contract::{ }; pub use self::signature::{extend_signature_with_id, sign_with_signature_id}; pub use self::traits::{ - FromAbi, FromPlainAbi, IgnoreName, IntoAbi, IntoPlainAbi, WithAbiType, WithPlainAbiType, + FromAbi, FromAbiIter, FromPlainAbi, IgnoreName, IntoAbi, IntoPlainAbi, WithAbiType, + WithPlainAbiType, }; pub use self::ty::{AbiHeaderType, AbiType, NamedAbiType, PlainAbiType}; pub use self::value::{AbiHeader, AbiValue, NamedAbiValue, PlainAbiValue}; diff --git a/src/abi/traits.rs b/src/abi/traits.rs index da81d35e..2aaafb05 100644 --- a/src/abi/traits.rs +++ b/src/abi/traits.rs @@ -1131,6 +1131,34 @@ impl FromAbi for Rc { } } +/// A wrapper around ABI values iterator that converts +/// each item using the [`FromAbi`] trait. +/// +/// It should be used to parse fields as tuple items +/// for some struct `T` (which must implement [`WithAbiType`]). +pub trait FromAbiIter { + /// Advances the iterator and returns the next value. + fn next_value(&mut self) -> Result; +} + +impl FromAbiIter for I +where + T: WithAbiType, + I: Iterator, +{ + fn next_value(&mut self) -> Result { + match Iterator::next(self) { + Some(value) => V::from_abi(value), + None => Err(anyhow::Error::from( + crate::abi::error::AbiError::TypeMismatch { + expected: T::abi_type().to_string().into_boxed_str(), + ty: Box::from("tuple part"), + }, + )), + } + } +} + #[cfg(test)] mod tests { use ahash::HashSet;