multiversx_sc/types/managed/wrapped/
managed_vec.rs

1use super::{EncodedManagedVecItem, ManagedVecItemPayload};
2use crate::{
3    abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName},
4    api::{ErrorApiImpl, InvalidSliceError, ManagedTypeApi},
5    codec::{
6        DecodeErrorHandler, EncodeErrorHandler, IntoMultiValue, NestedDecode, NestedDecodeInput,
7        NestedEncode, NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode,
8        TopEncodeMultiOutput, TopEncodeOutput,
9    },
10    types::{
11        ManagedBuffer, ManagedBufferNestedDecodeInput, ManagedType, ManagedVecItem,
12        ManagedVecRefIterator, ManagedVecRefMut, MultiValueEncoded, MultiValueManagedVec,
13    },
14};
15use alloc::{format, vec::Vec};
16use core::{
17    borrow::Borrow,
18    cmp::Ordering,
19    fmt::Debug,
20    iter::FromIterator,
21    marker::PhantomData,
22    mem::{transmute_copy, ManuallyDrop, MaybeUninit},
23};
24
25pub(crate) const INDEX_OUT_OF_RANGE_MSG: &[u8] = b"ManagedVec index out of range";
26
27/// A list of items that lives inside a managed buffer.
28/// Items can be either stored there in full (e.g. `u32`),
29/// or just via handle (e.g. `BigUint<M>`).
30#[repr(transparent)]
31pub struct ManagedVec<M, T>
32where
33    M: ManagedTypeApi,
34    T: ManagedVecItem,
35{
36    pub(crate) buffer: ManagedBuffer<M>,
37    _phantom: PhantomData<T>,
38}
39
40impl<M, T> ManagedType<M> for ManagedVec<M, T>
41where
42    M: ManagedTypeApi,
43    T: ManagedVecItem,
44{
45    type OwnHandle = M::ManagedBufferHandle;
46
47    #[inline]
48    unsafe fn from_handle(handle: M::ManagedBufferHandle) -> Self {
49        ManagedVec {
50            buffer: ManagedBuffer::from_handle(handle),
51            _phantom: PhantomData,
52        }
53    }
54
55    fn get_handle(&self) -> M::ManagedBufferHandle {
56        self.buffer.get_handle()
57    }
58
59    unsafe fn forget_into_handle(self) -> Self::OwnHandle {
60        self.buffer.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> ManagedVec<M, T>
73where
74    M: ManagedTypeApi,
75    T: ManagedVecItem,
76{
77    #[inline]
78    pub fn new() -> Self {
79        ManagedVec {
80            buffer: ManagedBuffer::new(),
81            _phantom: PhantomData,
82        }
83    }
84
85    #[inline]
86    pub(crate) fn new_from_raw_buffer(buffer: ManagedBuffer<M>) -> Self {
87        ManagedVec {
88            buffer,
89            _phantom: PhantomData,
90        }
91    }
92
93    /// Creates a new object, without initializing it.
94    ///
95    /// ## Safety
96    ///
97    /// The value needs to be initialized after creation, otherwise the VM will halt the first time the value is attempted to be read.
98    pub unsafe fn new_uninit() -> Self {
99        ManagedVec {
100            buffer: ManagedBuffer::new_uninit(),
101            _phantom: PhantomData,
102        }
103    }
104}
105
106impl<M, T, I> From<Vec<I>> for ManagedVec<M, T>
107where
108    M: ManagedTypeApi,
109    T: ManagedVecItem,
110    I: Into<T>,
111{
112    fn from(v: Vec<I>) -> Self {
113        let mut result = Self::new();
114        for item in v.into_iter() {
115            result.push(item.into());
116        }
117        result
118    }
119}
120
121impl<M, T> Default for ManagedVec<M, T>
122where
123    M: ManagedTypeApi,
124    T: ManagedVecItem,
125{
126    #[inline]
127    fn default() -> Self {
128        Self::new()
129    }
130}
131
132impl<M, T> ManagedVec<M, T>
133where
134    M: ManagedTypeApi,
135    T: ManagedVecItem,
136{
137    /// Length of the underlying buffer in bytes.
138    #[inline]
139    pub fn byte_len(&self) -> usize {
140        self.buffer.len()
141    }
142
143    /// Number of items.
144    #[inline]
145    pub fn len(&self) -> usize {
146        self.byte_len() / T::payload_size()
147    }
148
149    #[inline]
150    pub fn is_empty(&self) -> bool {
151        self.byte_len() == 0
152    }
153
154    /// Internal function that loads the payload for an item.
155    ///
156    /// Payload passed as mutable reference, to avoid copying of bytes around the stack.
157    fn load_item_payload(&self, index: usize, payload: &mut T::PAYLOAD) -> bool {
158        let byte_index = index * T::payload_size();
159
160        if byte_index + T::payload_size() > self.byte_len() {
161            return false;
162        }
163
164        self.buffer
165            .load_slice(byte_index, payload.payload_slice_mut());
166
167        true
168    }
169
170    pub fn try_get(&self, index: usize) -> Option<T::Ref<'_>> {
171        let mut payload = T::PAYLOAD::new_buffer();
172        if self.load_item_payload(index, &mut payload) {
173            unsafe { Some(T::borrow_from_payload(&payload)) }
174        } else {
175            None
176        }
177    }
178
179    /// Extracts all elements to an array, if the length matches exactly.
180    ///
181    /// The resulting array contains mere references to the items, as defined in `ManagedVecItem`.
182    pub fn to_array_of_refs<const N: usize>(&self) -> Option<[T::Ref<'_>; N]> {
183        if self.len() != N {
184            return None;
185        }
186
187        let mut result_uninit =
188            unsafe { MaybeUninit::<[MaybeUninit<T::Ref<'_>>; N]>::uninit().assume_init() };
189
190        for (index, value) in self.iter().enumerate() {
191            // length already checked
192            unsafe {
193                result_uninit.get_unchecked_mut(index).write(value);
194            }
195        }
196
197        let result = unsafe { transmute_copy(&ManuallyDrop::new(result_uninit)) };
198        Some(result)
199    }
200
201    /// Retrieves element at index, if the index is valid.
202    /// Otherwise, signals an error and terminates execution.
203    pub fn get(&self, index: usize) -> T::Ref<'_> {
204        match self.try_get(index) {
205            Some(result) => result,
206            None => M::error_api_impl().signal_error(INDEX_OUT_OF_RANGE_MSG),
207        }
208    }
209
210    /// If it contains precisely one item, will return `Some` with a reference to that item.
211    ///
212    /// Will return `None` for zero or more than one item.
213    pub fn is_single_item(&self) -> Option<T::Ref<'_>> {
214        let mut payload = T::PAYLOAD::new_buffer();
215        if self.len() == 1 {
216            let _ = self.load_item_payload(0, &mut payload);
217            unsafe { Some(T::borrow_from_payload(&payload)) }
218        } else {
219            None
220        }
221    }
222
223    pub fn get_mut(&mut self, index: usize) -> ManagedVecRefMut<'_, M, T> {
224        ManagedVecRefMut::new(self.get_handle(), index)
225    }
226
227    pub(super) unsafe fn get_unsafe(&self, index: usize) -> T {
228        let mut payload = T::PAYLOAD::new_buffer();
229        if self.load_item_payload(index, &mut payload) {
230            T::read_from_payload(&payload)
231        } else {
232            M::error_api_impl().signal_error(INDEX_OUT_OF_RANGE_MSG);
233        }
234    }
235
236    pub fn set(&mut self, index: usize, item: T) -> Result<(), InvalidSliceError> {
237        let byte_index = index * T::payload_size();
238        let mut payload = T::PAYLOAD::new_buffer();
239        item.save_to_payload(&mut payload);
240        self.buffer.set_slice(byte_index, payload.payload_slice())
241    }
242
243    /// Returns a new `ManagedVec`, containing the [start_index, end_index) range of elements.
244    /// Returns `None` if any index is out of range
245    pub fn slice(&self, start_index: usize, end_index: usize) -> Option<Self> {
246        let byte_start = start_index * T::payload_size();
247        let byte_end = end_index * T::payload_size();
248        let opt_buffer = self.buffer.copy_slice(byte_start, byte_end - byte_start);
249        opt_buffer.map(ManagedVec::new_from_raw_buffer)
250    }
251
252    pub fn push(&mut self, item: T) {
253        let mut payload = T::PAYLOAD::new_buffer();
254        item.save_to_payload(&mut payload);
255        self.buffer.append_bytes(payload.payload_slice());
256    }
257
258    pub fn remove(&mut self, index: usize) {
259        let len = self.len();
260        if index >= len {
261            M::error_api_impl().signal_error(INDEX_OUT_OF_RANGE_MSG);
262        }
263
264        let part_before = if index > 0 {
265            match self.slice(0, index) {
266                Some(s) => s,
267                None => M::error_api_impl().signal_error(INDEX_OUT_OF_RANGE_MSG),
268            }
269        } else {
270            ManagedVec::new()
271        };
272        let part_after = if index < len {
273            match self.slice(index + 1, len) {
274                Some(s) => s,
275                None => M::error_api_impl().signal_error(INDEX_OUT_OF_RANGE_MSG),
276            }
277        } else {
278            ManagedVec::new()
279        };
280
281        *self = part_before;
282        self.buffer.append(&part_after.buffer);
283    }
284
285    pub fn take(&mut self, index: usize) -> T {
286        let item = unsafe { self.get_unsafe(index) };
287        self.remove(index);
288        item
289    }
290
291    /// New `ManagedVec` instance with 1 element in it.
292    pub fn from_single_item(item: T) -> Self {
293        let mut result = ManagedVec::new();
294        result.push(item);
295        result
296    }
297
298    pub fn overwrite_with_single_item(&mut self, item: T) {
299        let mut payload = T::PAYLOAD::new_buffer();
300        item.save_to_payload(&mut payload);
301        self.buffer.overwrite(payload.payload_slice());
302    }
303
304    /// Appends all the contents of another managed vec at the end of the current one.
305    /// Consumes the other vec in the process.
306    pub fn append_vec(&mut self, item: ManagedVec<M, T>) {
307        self.buffer.append(&item.buffer);
308    }
309
310    /// Removes all items while retaining the handle.
311    pub fn clear(&mut self) {
312        self.buffer.overwrite(&[]);
313    }
314
315    #[cfg(feature = "alloc")]
316    pub fn into_vec(self) -> Vec<T> {
317        let mut v = Vec::new();
318        for item in self.into_iter() {
319            v.push(item);
320        }
321        v
322    }
323
324    /// Temporarily converts self to a `Vec<T>`.
325    /// All operations performed on the temporary vector get saved back to the underlying buffer.
326    #[cfg(feature = "alloc")]
327    pub fn with_self_as_vec<R, F>(&mut self, f: F) -> R
328    where
329        F: FnOnce(&mut Vec<T>) -> R,
330    {
331        let new = ManagedVec::new();
332        let old = core::mem::replace(self, new);
333        let mut temp_vec = Vec::new();
334        for item in old.into_iter() {
335            temp_vec.push(item);
336        }
337        let result = f(&mut temp_vec);
338        for new_item in temp_vec {
339            self.push(new_item);
340        }
341        result
342    }
343
344    pub fn iter(&self) -> ManagedVecRefIterator<'_, M, T> {
345        ManagedVecRefIterator::new(self)
346    }
347
348    /// Creates a reference to and identical object, but one which behaves like a multi-value-vec.
349    pub fn as_multi(&self) -> &MultiValueManagedVec<M, T> {
350        MultiValueManagedVec::transmute_from_handle_ref(&self.buffer.handle)
351    }
352}
353
354impl<M, T> ManagedVec<M, T>
355where
356    M: ManagedTypeApi,
357    T: ManagedVecItem + Debug,
358{
359    fn with_self_as_slice<R, F>(&self, f: F) -> R
360    where
361        F: FnOnce(&[EncodedManagedVecItem<T>]) -> R,
362    {
363        self.buffer.with_buffer_contents(|bytes| {
364            let item_len = bytes.len() / T::payload_size();
365            let values = Self::transmute_slice(bytes, item_len);
366            f(values)
367        })
368    }
369
370    fn with_self_as_slice_mut<F>(&mut self, f: F)
371    where
372        F: FnOnce(&mut [EncodedManagedVecItem<T>]) -> &[EncodedManagedVecItem<T>],
373    {
374        self.buffer.with_buffer_contents_mut(|bytes| {
375            let item_len = bytes.len() / T::payload_size();
376            let values = Self::transmute_slice_mut(bytes, item_len);
377
378            let result = f(values);
379            let result_len = result.len() * T::payload_size();
380            Self::transmute_slice(result, result_len)
381        });
382    }
383
384    fn transmute_slice<T1, T2>(from: &[T1], len: usize) -> &[T2] {
385        unsafe {
386            let ptr = from.as_ptr() as *const T2;
387            core::slice::from_raw_parts(ptr, len)
388        }
389    }
390
391    fn transmute_slice_mut<T1, T2>(from: &mut [T1], len: usize) -> &mut [T2] {
392        unsafe {
393            let ptr = from.as_mut_ptr() as *mut T2;
394            core::slice::from_raw_parts_mut(ptr, len)
395        }
396    }
397}
398
399impl<M, T> ManagedVec<M, T>
400where
401    M: ManagedTypeApi,
402    T: ManagedVecItem + Ord + Debug,
403{
404    #[deprecated(since = "0.54.5", note = "Please use method `sort_unstable` instead.")]
405    #[cfg(feature = "alloc")]
406    pub fn sort(&mut self) {
407        self.with_self_as_slice_mut(|slice| {
408            slice.sort();
409            slice
410        });
411    }
412
413    #[deprecated(
414        since = "0.54.5",
415        note = "Please use method `sort_unstable_by` instead."
416    )]
417    #[cfg(feature = "alloc")]
418    pub fn sort_by<F>(&mut self, mut compare: F)
419    where
420        F: FnMut(&T, &T) -> Ordering,
421    {
422        self.with_self_as_slice_mut(|slice| {
423            slice.sort_by(|a, b| compare(&a.decode(), &b.decode()));
424            slice
425        });
426    }
427
428    #[deprecated(
429        since = "0.54.5",
430        note = "Please use method `sort_unstable_by_key` instead."
431    )]
432    #[cfg(feature = "alloc")]
433    pub fn sort_by_key<K, F>(&mut self, mut f: F)
434    where
435        F: FnMut(&T) -> K,
436        K: Ord,
437    {
438        self.with_self_as_slice_mut(|slice| {
439            slice.sort_by_key(|a| f(&a.decode()));
440            slice
441        });
442    }
443
444    #[deprecated]
445    #[cfg(feature = "alloc")]
446    pub fn sort_by_cached_key<K, F>(&mut self, mut f: F)
447    where
448        F: FnMut(&T) -> K,
449        K: Ord,
450    {
451        self.with_self_as_slice_mut(|slice| {
452            slice.sort_by_cached_key(|a| f(&a.decode()));
453            slice
454        });
455    }
456
457    pub fn sort_unstable(&mut self) {
458        self.with_self_as_slice_mut(|slice| {
459            slice.sort_unstable();
460            slice
461        })
462    }
463
464    pub fn sort_unstable_by<F>(&mut self, mut compare: F)
465    where
466        F: FnMut(&T, &T) -> Ordering,
467    {
468        self.with_self_as_slice_mut(|slice| {
469            slice.sort_unstable_by(|a, b| compare(&a.decode(), &b.decode()));
470            slice
471        })
472    }
473
474    pub fn sort_unstable_by_key<K, F>(&mut self, mut f: F)
475    where
476        F: FnMut(&T) -> K,
477        K: Ord,
478    {
479        self.with_self_as_slice_mut(|slice| {
480            slice.sort_unstable_by_key(|a| f(&a.decode()));
481            slice
482        })
483    }
484
485    pub fn is_sorted(&self) -> bool {
486        self.with_self_as_slice(|slice| {
487            let mut slice_iter = slice.iter();
488            #[inline]
489            fn check<'a, T>(
490                last: &'a mut T,
491                mut compare: impl FnMut(&T, &T) -> Option<Ordering> + 'a,
492            ) -> impl FnMut(T) -> bool + 'a {
493                move |curr| {
494                    if let Some(Ordering::Greater) | None = compare(last, &curr) {
495                        return false;
496                    }
497                    *last = curr;
498                    true
499                }
500            }
501
502            let mut last = match slice_iter.next() {
503                Some(e) => e,
504                None => return true,
505            };
506
507            slice_iter.all(check(&mut last, PartialOrd::partial_cmp))
508        })
509    }
510}
511
512impl<M, T> ManagedVec<M, T>
513where
514    M: ManagedTypeApi,
515    T: ManagedVecItem + PartialEq + Debug,
516{
517    pub fn dedup(&mut self) {
518        self.with_self_as_slice_mut(|slice| {
519            let same_bucket = |a, b| a == b;
520            let len = slice.len();
521            if len <= 1 {
522                return slice;
523            }
524
525            let ptr = slice.as_mut_ptr();
526            let mut next_read: usize = 1;
527            let mut next_write: usize = 1;
528            unsafe {
529                // Avoid bounds checks by using raw pointers.
530                while next_read < len {
531                    let ptr_read = ptr.add(next_read);
532                    let prev_ptr_write = ptr.add(next_write - 1);
533                    if !same_bucket(&mut *ptr_read, &mut *prev_ptr_write) {
534                        if next_read != next_write {
535                            let ptr_write = prev_ptr_write.add(1);
536                            core::ptr::swap(ptr_read, ptr_write);
537                        }
538                        next_write += 1;
539                    }
540                    next_read += 1;
541                }
542            }
543
544            let (dedup, _) = slice.split_at_mut(next_write);
545            dedup
546        })
547    }
548}
549
550impl<M, T> Clone for ManagedVec<M, T>
551where
552    M: ManagedTypeApi,
553    T: ManagedVecItem + Clone,
554{
555    fn clone(&self) -> Self {
556        let mut result = ManagedVec::new();
557        for item in self.into_iter() {
558            result.push(item.borrow().clone())
559        }
560        result
561    }
562}
563
564impl<M, T> PartialEq for ManagedVec<M, T>
565where
566    M: ManagedTypeApi,
567    T: ManagedVecItem + PartialEq,
568{
569    #[inline]
570    fn eq(&self, other: &Self) -> bool {
571        if self.buffer == other.buffer {
572            return true;
573        }
574        let self_len = self.buffer.byte_len();
575        let other_len = other.buffer.byte_len();
576        if self_len != other_len {
577            return false;
578        }
579        let mut byte_index = 0;
580        while byte_index < self_len {
581            let mut self_payload = T::PAYLOAD::new_buffer();
582            self.buffer
583                .load_slice(byte_index, self_payload.payload_slice_mut());
584            let mut other_payload = T::PAYLOAD::new_buffer();
585            other
586                .buffer
587                .load_slice(byte_index, other_payload.payload_slice_mut());
588            let self_item = T::read_from_payload(&self_payload);
589            let other_item = T::read_from_payload(&other_payload);
590            if self_item != other_item {
591                return false;
592            }
593            byte_index += T::payload_size();
594        }
595        true
596    }
597}
598
599impl<M, T> Eq for ManagedVec<M, T>
600where
601    M: ManagedTypeApi,
602    T: ManagedVecItem + PartialEq,
603{
604}
605
606impl<M, T> ManagedVec<M, T>
607where
608    M: ManagedTypeApi,
609    T: ManagedVecItem + PartialEq,
610{
611    /// This can be very costly for big collections.
612    /// It needs to deserialize and compare every single item in the worst case.
613    pub fn find(&self, item: &T) -> Option<usize> {
614        for (i, item_in_vec) in self.iter().enumerate() {
615            if item_in_vec.borrow() == item {
616                return Some(i);
617            }
618        }
619
620        None
621    }
622
623    /// This can be very costly for big collections.
624    /// It needs to iterate, deserialize, and compare every single item in the worst case.
625    #[inline]
626    pub fn contains(&self, item: &T) -> bool {
627        self.find(item).is_some()
628    }
629}
630
631impl<M, T> TopEncode for ManagedVec<M, T>
632where
633    M: ManagedTypeApi,
634    T: ManagedVecItem + NestedEncode,
635{
636    #[inline]
637    fn top_encode_or_handle_err<O, H>(&self, output: O, h: H) -> Result<(), H::HandledErr>
638    where
639        O: TopEncodeOutput,
640        H: EncodeErrorHandler,
641    {
642        if T::SKIPS_RESERIALIZATION {
643            self.buffer.top_encode_or_handle_err(output, h)
644        } else {
645            let mut nested_buffer = output.start_nested_encode();
646            for item in self {
647                item.borrow()
648                    .dep_encode_or_handle_err(&mut nested_buffer, h)?;
649            }
650            output.finalize_nested_encode(nested_buffer);
651            Ok(())
652        }
653    }
654}
655
656impl<M, T> NestedEncode for ManagedVec<M, T>
657where
658    M: ManagedTypeApi,
659    T: ManagedVecItem + NestedEncode,
660{
661    fn dep_encode_or_handle_err<O, H>(&self, dest: &mut O, h: H) -> Result<(), H::HandledErr>
662    where
663        O: NestedEncodeOutput,
664        H: EncodeErrorHandler,
665    {
666        self.len().dep_encode_or_handle_err(dest, h)?;
667        for item in self {
668            item.borrow().dep_encode_or_handle_err(dest, h)?;
669        }
670        Ok(())
671    }
672}
673
674impl<M, T> TopDecode for ManagedVec<M, T>
675where
676    M: ManagedTypeApi,
677    T: ManagedVecItem + NestedDecode,
678{
679    fn top_decode_or_handle_err<I, H>(input: I, h: H) -> Result<Self, H::HandledErr>
680    where
681        I: TopDecodeInput,
682        H: DecodeErrorHandler,
683    {
684        let buffer = ManagedBuffer::top_decode_or_handle_err(input, h)?;
685        if T::SKIPS_RESERIALIZATION {
686            Ok(ManagedVec::new_from_raw_buffer(buffer))
687        } else {
688            let mut result = ManagedVec::new();
689            let mut nested_de_input = ManagedBufferNestedDecodeInput::new(buffer);
690            while nested_de_input.remaining_len() > 0 {
691                result.push(T::dep_decode_or_handle_err(&mut nested_de_input, h)?);
692            }
693            Ok(result)
694        }
695    }
696}
697
698impl<M, T> NestedDecode for ManagedVec<M, T>
699where
700    M: ManagedTypeApi,
701    T: ManagedVecItem + NestedDecode,
702{
703    fn dep_decode_or_handle_err<I, H>(input: &mut I, h: H) -> Result<Self, H::HandledErr>
704    where
705        I: NestedDecodeInput,
706        H: DecodeErrorHandler,
707    {
708        let size = usize::dep_decode_or_handle_err(input, h)?;
709        let mut result = ManagedVec::new();
710        for _ in 0..size {
711            result.push(T::dep_decode_or_handle_err(input, h)?);
712        }
713        Ok(result)
714    }
715}
716
717impl<M, T> IntoMultiValue for ManagedVec<M, T>
718where
719    M: ManagedTypeApi,
720    T: ManagedVecItem + IntoMultiValue,
721{
722    type MultiValue = MultiValueEncoded<M, T::MultiValue>;
723
724    fn into_multi_value(self) -> Self::MultiValue {
725        let mut result = MultiValueEncoded::new();
726        for item in self.into_iter() {
727            result.push(item.into_multi_value());
728        }
729        result
730    }
731}
732
733impl<M, T, U> TypeAbiFrom<ManagedVec<M, U>> for ManagedVec<M, T>
734where
735    M: ManagedTypeApi,
736    U: ManagedVecItem,
737    T: ManagedVecItem + TypeAbiFrom<U>,
738{
739}
740
741impl<M, T, U> TypeAbiFrom<Vec<U>> for ManagedVec<M, T>
742where
743    M: ManagedTypeApi,
744    T: ManagedVecItem + TypeAbiFrom<U>,
745{
746}
747
748impl<M, T, U> TypeAbiFrom<ManagedVec<M, U>> for Vec<T>
749where
750    M: ManagedTypeApi,
751    U: ManagedVecItem,
752    T: TypeAbiFrom<U>,
753{
754}
755
756impl<M, T> TypeAbi for ManagedVec<M, T>
757where
758    M: ManagedTypeApi,
759    T: ManagedVecItem + TypeAbi,
760{
761    type Unmanaged = Vec<T::Unmanaged>;
762
763    /// It is semantically equivalent to any list of `T`.
764    fn type_name() -> TypeName {
765        <&[T] as TypeAbi>::type_name()
766    }
767
768    fn type_name_rust() -> TypeName {
769        format!("ManagedVec<$API, {}>", T::type_name_rust())
770    }
771
772    fn provide_type_descriptions<TDC: TypeDescriptionContainer>(accumulator: &mut TDC) {
773        T::provide_type_descriptions(accumulator);
774    }
775}
776
777impl<M, T> core::fmt::Debug for ManagedVec<M, T>
778where
779    M: ManagedTypeApi,
780    T: ManagedVecItem + core::fmt::Debug + Clone,
781{
782    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
783        let mut dbg_list = f.debug_list();
784        for item in self.into_iter() {
785            dbg_list.entry(item.borrow());
786        }
787        dbg_list.finish()
788    }
789}
790
791impl<M> TopEncodeMultiOutput for ManagedVec<M, ManagedBuffer<M>>
792where
793    M: ManagedTypeApi,
794{
795    fn push_single_value<T, H>(&mut self, arg: &T, h: H) -> Result<(), H::HandledErr>
796    where
797        T: TopEncode,
798        H: EncodeErrorHandler,
799    {
800        let mut result = ManagedBuffer::new();
801        arg.top_encode_or_handle_err(&mut result, h)?;
802        self.push(result);
803        Ok(())
804    }
805}
806
807impl<M, V> FromIterator<V> for ManagedVec<M, V>
808where
809    M: ManagedTypeApi,
810    V: ManagedVecItem,
811{
812    fn from_iter<T: IntoIterator<Item = V>>(iter: T) -> Self {
813        let mut result: ManagedVec<M, V> = ManagedVec::new();
814        iter.into_iter().for_each(|f| result.push(f));
815        result
816    }
817}
818
819impl<M, V> Extend<V> for ManagedVec<M, V>
820where
821    M: ManagedTypeApi,
822    V: ManagedVecItem,
823{
824    fn extend<T: IntoIterator<Item = V>>(&mut self, iter: T) {
825        for elem in iter {
826            self.push(elem);
827        }
828    }
829}