Skip to main content

multiversx_sc/types/managed/multi_value/
multi_value_managed_vec.rs

1use core::borrow::Borrow;
2
3use multiversx_sc_codec::multi_types::{IgnoreValue, MultiValueVec};
4
5use crate::{
6    abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName},
7    api::ManagedTypeApi,
8    codec::{
9        DecodeErrorHandler, EncodeErrorHandler, TopDecodeMulti, TopDecodeMultiInput,
10        TopEncodeMulti, TopEncodeMultiOutput, Vec,
11    },
12    types::{ManagedType, ManagedVecOwnedIterator},
13};
14
15use crate::types::{ManagedVec, ManagedVecItem, ManagedVecRefIterator};
16
17#[derive(Clone, Default)]
18pub struct MultiValueManagedVec<M: ManagedTypeApi, T: ManagedVecItem>(ManagedVec<M, T>);
19
20#[deprecated(
21    since = "0.29.0",
22    note = "Alias kept for backwards compatibility. Replace with `MultiValueManagedVec`"
23)]
24pub type ManagedVarArgsEager<M, T> = MultiValueManagedVec<M, T>;
25
26#[deprecated(
27    since = "0.29.0",
28    note = "Alias kept for backwards compatibility. Replace with `MultiValueManagedVec`"
29)]
30pub type ManagedMultiResultVecEager<M, T> = MultiValueManagedVec<M, T>;
31
32impl<M, T> From<ManagedVec<M, T>> for MultiValueManagedVec<M, T>
33where
34    M: ManagedTypeApi,
35    T: ManagedVecItem,
36{
37    #[inline]
38    fn from(managed_vec: ManagedVec<M, T>) -> Self {
39        MultiValueManagedVec(managed_vec)
40    }
41}
42
43impl<M, T> ManagedType<M> for MultiValueManagedVec<M, T>
44where
45    M: ManagedTypeApi,
46    T: ManagedVecItem,
47{
48    type OwnHandle = M::ManagedBufferHandle;
49
50    #[inline]
51    unsafe fn from_handle(handle: M::ManagedBufferHandle) -> Self {
52        unsafe { Self(ManagedVec::from_handle(handle)) }
53    }
54
55    fn get_handle(&self) -> M::ManagedBufferHandle {
56        self.0.get_handle()
57    }
58
59    unsafe fn forget_into_handle(self) -> Self::OwnHandle {
60        unsafe { self.0.forget_into_handle() }
61    }
62
63    fn transmute_from_handle_ref(handle_ref: &M::ManagedBufferHandle) -> &Self {
64        unsafe { core::mem::transmute(handle_ref) }
65    }
66
67    fn transmute_from_handle_ref_mut(handle_ref: &mut M::ManagedBufferHandle) -> &mut Self {
68        unsafe { core::mem::transmute(handle_ref) }
69    }
70}
71
72impl<M, T> MultiValueManagedVec<M, T>
73where
74    M: ManagedTypeApi,
75    T: ManagedVecItem,
76{
77    #[inline]
78    pub fn new() -> Self {
79        MultiValueManagedVec(ManagedVec::new())
80    }
81
82    #[inline]
83    pub fn byte_len(&self) -> usize {
84        self.0.byte_len()
85    }
86
87    #[inline]
88    pub fn len(&self) -> usize {
89        self.0.len()
90    }
91
92    #[inline]
93    pub fn is_empty(&self) -> bool {
94        self.0.is_empty()
95    }
96
97    pub fn get(&self, index: usize) -> T::Ref<'_> {
98        self.0.get(index)
99    }
100
101    #[allow(clippy::redundant_closure)]
102    pub fn slice(&self, start_index: usize, end_index: usize) -> Option<Self> {
103        self.0
104            .slice(start_index, end_index)
105            .map(|value| Self(value))
106    }
107
108    pub fn push(&mut self, item: T) {
109        self.0.push(item)
110    }
111
112    pub fn from_single_item(item: T) -> Self {
113        let mut result = MultiValueManagedVec::new();
114        result.push(item);
115        result
116    }
117
118    pub fn overwrite_with_single_item(&mut self, item: T) {
119        self.0.overwrite_with_single_item(item)
120    }
121
122    pub fn append_vec(&mut self, item: MultiValueManagedVec<M, T>) {
123        self.0.append_vec(item.0)
124    }
125
126    pub fn clear(&mut self) {
127        self.0.clear()
128    }
129
130    pub fn into_vec(self) -> ManagedVec<M, T> {
131        self.0
132    }
133
134    pub fn as_vec(&self) -> &ManagedVec<M, T> {
135        &self.0
136    }
137
138    #[cfg(feature = "alloc")]
139    pub fn with_self_as_vec<F>(&mut self, f: F)
140    where
141        F: FnOnce(&mut Vec<T>),
142    {
143        self.0.with_self_as_vec(f)
144    }
145
146    pub fn iter(&self) -> ManagedVecRefIterator<'_, M, T> {
147        ManagedVecRefIterator::new(&self.0)
148    }
149}
150
151impl<M, T> IntoIterator for MultiValueManagedVec<M, T>
152where
153    M: ManagedTypeApi,
154    T: ManagedVecItem,
155{
156    type Item = T;
157
158    type IntoIter = ManagedVecOwnedIterator<M, T>;
159
160    fn into_iter(self) -> Self::IntoIter {
161        self.0.into_iter()
162    }
163}
164
165impl<'a, M, T> IntoIterator for &'a MultiValueManagedVec<M, T>
166where
167    M: ManagedTypeApi,
168    T: ManagedVecItem,
169{
170    type Item = T::Ref<'a>;
171
172    type IntoIter = ManagedVecRefIterator<'a, M, T>;
173
174    fn into_iter(self) -> Self::IntoIter {
175        self.iter()
176    }
177}
178
179impl<M, T, I> From<Vec<I>> for MultiValueManagedVec<M, T>
180where
181    M: ManagedTypeApi,
182    T: ManagedVecItem,
183    I: Into<T>,
184{
185    fn from(v: Vec<I>) -> Self {
186        let mut result = Self::new();
187        for item in v.into_iter() {
188            result.push(item.into());
189        }
190        result
191    }
192}
193
194impl<M, T> TopEncodeMulti for &MultiValueManagedVec<M, T>
195where
196    M: ManagedTypeApi,
197    T: ManagedVecItem + TopEncodeMulti,
198{
199    fn multi_encode_or_handle_err<O, H>(&self, output: &mut O, h: H) -> Result<(), H::HandledErr>
200    where
201        O: TopEncodeMultiOutput,
202        H: EncodeErrorHandler,
203    {
204        for elem in &self.0 {
205            elem.borrow().multi_encode_or_handle_err(output, h)?;
206        }
207        Ok(())
208    }
209}
210
211impl<M, T> TopEncodeMulti for MultiValueManagedVec<M, T>
212where
213    M: ManagedTypeApi,
214    T: ManagedVecItem + TopEncodeMulti,
215{
216    fn multi_encode_or_handle_err<O, H>(&self, output: &mut O, h: H) -> Result<(), H::HandledErr>
217    where
218        O: TopEncodeMultiOutput,
219        H: EncodeErrorHandler,
220    {
221        (&self).multi_encode_or_handle_err(output, h)
222    }
223}
224
225impl<M, T> TopDecodeMulti for MultiValueManagedVec<M, T>
226where
227    M: ManagedTypeApi,
228    T: ManagedVecItem + TopDecodeMulti,
229{
230    fn multi_decode_or_handle_err<I, H>(input: &mut I, h: H) -> Result<Self, H::HandledErr>
231    where
232        I: TopDecodeMultiInput,
233        H: DecodeErrorHandler,
234    {
235        let mut result_vec: ManagedVec<M, T> = ManagedVec::new();
236        while input.has_next() {
237            result_vec.push(T::multi_decode_or_handle_err(input, h)?);
238        }
239        Ok(MultiValueManagedVec(result_vec))
240    }
241}
242
243impl<M, T, U> TypeAbiFrom<MultiValueManagedVec<M, U>> for MultiValueManagedVec<M, T>
244where
245    M: ManagedTypeApi,
246    T: ManagedVecItem + TypeAbi + TypeAbiFrom<U>,
247    U: ManagedVecItem + TypeAbi,
248{
249}
250
251impl<M, T, U> TypeAbiFrom<&MultiValueManagedVec<M, U>> for MultiValueManagedVec<M, T>
252where
253    M: ManagedTypeApi,
254    T: ManagedVecItem + TypeAbi + TypeAbiFrom<U>,
255    U: ManagedVecItem + TypeAbi,
256{
257}
258
259impl<M, T, U> TypeAbiFrom<MultiValueVec<U>> for MultiValueManagedVec<M, T>
260where
261    M: ManagedTypeApi,
262    T: ManagedVecItem + TypeAbi + TypeAbiFrom<U>,
263    U: TypeAbi,
264{
265}
266
267impl<M, T> TypeAbiFrom<IgnoreValue> for MultiValueManagedVec<M, T>
268where
269    M: ManagedTypeApi,
270    T: ManagedVecItem + TypeAbi,
271{
272}
273
274impl<M, T: TypeAbi> TypeAbi for MultiValueManagedVec<M, T>
275where
276    M: ManagedTypeApi,
277    T: ManagedVecItem,
278{
279    type Unmanaged = MultiValueVec<T::Unmanaged>;
280
281    fn type_name() -> TypeName {
282        crate::abi::type_name_variadic::<T>()
283    }
284
285    fn type_name_rust() -> TypeName {
286        alloc::format!("MultiValueManagedVec<$API, {}>", T::type_name_rust())
287    }
288
289    fn provide_type_descriptions<TDC: TypeDescriptionContainer>(accumulator: &mut TDC) {
290        T::provide_type_descriptions(accumulator);
291    }
292
293    fn is_variadic() -> bool {
294        true
295    }
296}