multiversx_sc/types/managed/multi_value/
multi_value_managed_vec_counted.rs

1use core::borrow::Borrow;
2
3use crate::{
4    abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName},
5    api::ManagedTypeApi,
6    codec::{
7        DecodeErrorHandler, EncodeErrorHandler, TopDecodeMulti, TopDecodeMultiInput,
8        TopEncodeMulti, TopEncodeMultiOutput,
9    },
10    types::{ManagedVec, ManagedVecItem},
11};
12
13/// Argument or result that is made up of the argument count, followed by the arguments themselves.
14/// Think of it as a `VarArgs` preceded by the count.
15/// Unlike `MultiValueManagedVec` it deserializes eagerly.
16#[derive(Clone, Default)]
17pub struct MultiValueManagedVecCounted<M, T>
18where
19    M: ManagedTypeApi,
20    T: ManagedVecItem,
21{
22    pub(super) contents: ManagedVec<M, T>,
23}
24
25#[deprecated(
26    since = "0.29.0",
27    note = "Alias kept for backwards compatibility. Replace with `MultiValueManagedVecCounted`"
28)]
29pub type ManagedCountedVarArgs<M, T> = MultiValueManagedVecCounted<M, T>;
30
31#[deprecated(
32    since = "0.29.0",
33    note = "Alias kept for backwards compatibility. Replace with `MultiValueManagedVecCounted`"
34)]
35pub type ManagedCountedMultiResultVec<M, T> = MultiValueManagedVecCounted<M, T>;
36
37impl<M, T> MultiValueManagedVecCounted<M, T>
38where
39    M: ManagedTypeApi,
40    T: ManagedVecItem,
41{
42    #[inline]
43    pub fn new() -> Self {
44        MultiValueManagedVecCounted::from(ManagedVec::new())
45    }
46}
47
48impl<M, T> MultiValueManagedVecCounted<M, T>
49where
50    M: ManagedTypeApi,
51    T: ManagedVecItem,
52{
53    #[inline]
54    pub fn len(&self) -> usize {
55        self.contents.len()
56    }
57
58    #[inline]
59    pub fn is_empty(&self) -> bool {
60        self.contents.is_empty()
61    }
62}
63
64impl<M, T> MultiValueManagedVecCounted<M, T>
65where
66    M: ManagedTypeApi,
67    T: ManagedVecItem,
68{
69    #[inline]
70    pub fn push(&mut self, item: T) {
71        self.contents.push(item);
72    }
73
74    #[inline]
75    pub fn into_vec(self) -> ManagedVec<M, T> {
76        self.contents
77    }
78}
79
80impl<M, T> From<ManagedVec<M, T>> for MultiValueManagedVecCounted<M, T>
81where
82    M: ManagedTypeApi,
83    T: ManagedVecItem,
84{
85    #[inline]
86    #[rustfmt::skip]
87    fn from(v: ManagedVec<M, T>) -> Self {
88        MultiValueManagedVecCounted {
89            contents: v,
90        }
91    }
92}
93
94impl<M, T> ManagedVecItem for MultiValueManagedVecCounted<M, T>
95where
96    M: ManagedTypeApi,
97    T: ManagedVecItem,
98{
99    type PAYLOAD = <ManagedVec<M, T> as ManagedVecItem>::PAYLOAD;
100    const SKIPS_RESERIALIZATION: bool = false;
101    type Ref<'a> = Self;
102
103    fn read_from_payload(payload: &Self::PAYLOAD) -> Self {
104        Self::from(ManagedVec::<M, T>::read_from_payload(payload))
105    }
106
107    unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> {
108        Self::read_from_payload(payload)
109    }
110
111    fn save_to_payload(self, payload: &mut Self::PAYLOAD) {
112        self.contents.save_to_payload(payload);
113    }
114}
115
116impl<M, T> TopEncodeMulti for MultiValueManagedVecCounted<M, T>
117where
118    M: ManagedTypeApi,
119    T: ManagedVecItem + TopEncodeMulti,
120{
121    fn multi_encode_or_handle_err<O, H>(&self, output: &mut O, h: H) -> Result<(), H::HandledErr>
122    where
123        O: TopEncodeMultiOutput,
124        H: EncodeErrorHandler,
125    {
126        self.len().multi_encode_or_handle_err(output, h)?;
127        for elem in &self.contents {
128            elem.borrow().multi_encode_or_handle_err(output, h)?;
129        }
130        Ok(())
131    }
132}
133
134impl<M, T> TopDecodeMulti for MultiValueManagedVecCounted<M, T>
135where
136    M: ManagedTypeApi,
137    T: ManagedVecItem + TopDecodeMulti,
138{
139    fn multi_decode_or_handle_err<I, H>(input: &mut I, h: H) -> Result<Self, H::HandledErr>
140    where
141        I: TopDecodeMultiInput,
142        H: DecodeErrorHandler,
143    {
144        let count = usize::multi_decode_or_handle_err(input, h)?;
145        let mut result = MultiValueManagedVecCounted::new();
146        for _ in 0..count {
147            result.push(T::multi_decode_or_handle_err(input, h)?);
148        }
149        Ok(result)
150    }
151}
152
153impl<M, T> TypeAbiFrom<Self> for MultiValueManagedVecCounted<M, T>
154where
155    M: ManagedTypeApi,
156    T: ManagedVecItem + TypeAbi,
157{
158}
159
160impl<M, T> TypeAbi for MultiValueManagedVecCounted<M, T>
161where
162    M: ManagedTypeApi,
163    T: ManagedVecItem + TypeAbi,
164{
165    type Unmanaged = Self;
166
167    fn type_name() -> TypeName {
168        let mut repr = TypeName::from("counted-variadic<");
169        repr.push_str(T::type_name().as_str());
170        repr.push('>');
171        repr
172    }
173
174    fn provide_type_descriptions<TDC: TypeDescriptionContainer>(accumulator: &mut TDC) {
175        T::provide_type_descriptions(accumulator);
176    }
177
178    fn is_variadic() -> bool {
179        true
180    }
181}