multiversx_sc/types/managed/wrapped/
managed_address.rs

1use core::convert::{TryFrom, TryInto};
2
3use crate::{
4    abi::{TypeAbi, TypeAbiFrom, TypeName},
5    api::{use_raw_handle, ManagedTypeApi, RawHandle},
6    codec::{
7        DecodeError, DecodeErrorHandler, EncodeErrorHandler, NestedDecode, NestedDecodeInput,
8        NestedEncode, NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput,
9    },
10    formatter::{hex_util::encode_bytes_as_hex, FormatByteReceiver, SCLowerHex},
11    types::{heap::Address, ManagedBuffer, ManagedByteArray, ManagedType},
12};
13
14use super::ManagedRef;
15
16#[repr(transparent)]
17#[derive(Clone)]
18pub struct ManagedAddress<M: ManagedTypeApi> {
19    bytes: ManagedByteArray<M, 32>,
20}
21
22impl<M> ManagedAddress<M>
23where
24    M: ManagedTypeApi,
25{
26    #[inline]
27    pub fn from_address(address: &Address) -> Self {
28        Self::new_from_bytes(address.as_array())
29    }
30
31    #[inline]
32    pub fn zero() -> Self {
33        Self::new_from_bytes(&[0u8; 32])
34    }
35
36    pub fn to_address(&self) -> Address {
37        let mut result = Address::zero();
38        self.bytes.buffer.load_slice(0, result.as_mut());
39        result
40    }
41
42    #[inline]
43    pub fn is_zero(&self) -> bool {
44        self.bytes.buffer == &[0u8; 32]
45    }
46
47    #[inline]
48    pub fn new_from_bytes(bytes: &[u8; 32]) -> Self {
49        ManagedAddress {
50            bytes: ManagedByteArray::new_from_bytes(bytes),
51        }
52    }
53
54    /// Creates a new object, without initializing it.
55    ///
56    /// ## Safety
57    ///
58    /// The value needs to be initialized after creation, otherwise the VM will halt the first time the value is attempted to be read.
59    pub unsafe fn new_uninit() -> Self {
60        ManagedAddress {
61            bytes: ManagedByteArray::new_uninit(),
62        }
63    }
64
65    /// Creates a shared managed reference to a given raw handle.
66    ///
67    /// ## Safety
68    ///
69    /// The reference points to a shared value. Make sure the handle is not leaked.
70    pub unsafe fn temp_const_ref(
71        raw_handle: RawHandle,
72    ) -> ManagedRef<'static, M, ManagedAddress<M>> {
73        ManagedRef::wrap_handle(use_raw_handle(raw_handle))
74    }
75
76    #[inline]
77    pub fn as_managed_buffer(&self) -> &ManagedBuffer<M> {
78        self.bytes.as_managed_buffer()
79    }
80
81    #[inline]
82    pub fn as_managed_byte_array(&self) -> &ManagedByteArray<M, 32> {
83        &self.bytes
84    }
85
86    #[inline]
87    pub fn to_byte_array(&self) -> [u8; 32] {
88        self.bytes.to_byte_array()
89    }
90}
91
92impl<M> From<&Address> for ManagedAddress<M>
93where
94    M: ManagedTypeApi,
95{
96    #[inline]
97    fn from(address: &Address) -> Self {
98        Self::from_address(address)
99    }
100}
101
102impl<M> From<Address> for ManagedAddress<M>
103where
104    M: ManagedTypeApi,
105{
106    #[inline]
107    fn from(address: Address) -> Self {
108        Self::from(&address)
109    }
110}
111
112impl<M> From<&[u8; 32]> for ManagedAddress<M>
113where
114    M: ManagedTypeApi,
115{
116    #[inline]
117    fn from(bytes: &[u8; 32]) -> Self {
118        Self::new_from_bytes(bytes)
119    }
120}
121
122impl<M> From<[u8; 32]> for ManagedAddress<M>
123where
124    M: ManagedTypeApi,
125{
126    #[inline]
127    fn from(bytes: [u8; 32]) -> Self {
128        Self::new_from_bytes(&bytes)
129    }
130}
131
132impl<M> From<ManagedByteArray<M, 32>> for ManagedAddress<M>
133where
134    M: ManagedTypeApi,
135{
136    fn from(value: ManagedByteArray<M, 32>) -> Self {
137        Self { bytes: value }
138    }
139}
140
141impl<M> TryFrom<ManagedBuffer<M>> for ManagedAddress<M>
142where
143    M: ManagedTypeApi,
144{
145    type Error = DecodeError;
146
147    fn try_from(value: ManagedBuffer<M>) -> Result<Self, Self::Error> {
148        let bytes: ManagedByteArray<M, 32> = value.try_into()?;
149        Ok(bytes.into())
150    }
151}
152
153impl<M> ManagedType<M> for ManagedAddress<M>
154where
155    M: ManagedTypeApi,
156{
157    type OwnHandle = M::ManagedBufferHandle;
158
159    #[inline]
160    unsafe fn from_handle(handle: M::ManagedBufferHandle) -> Self {
161        ManagedAddress {
162            bytes: ManagedByteArray::from_handle(handle),
163        }
164    }
165
166    fn get_handle(&self) -> M::ManagedBufferHandle {
167        self.bytes.get_handle()
168    }
169
170    unsafe fn forget_into_handle(self) -> Self::OwnHandle {
171        self.bytes.forget_into_handle()
172    }
173
174    fn transmute_from_handle_ref(handle_ref: &M::ManagedBufferHandle) -> &Self {
175        unsafe { core::mem::transmute(handle_ref) }
176    }
177
178    fn transmute_from_handle_ref_mut(handle_ref: &mut M::ManagedBufferHandle) -> &mut Self {
179        unsafe { core::mem::transmute(handle_ref) }
180    }
181}
182
183impl<M> Default for ManagedAddress<M>
184where
185    M: ManagedTypeApi,
186{
187    #[inline]
188    fn default() -> Self {
189        Self::zero()
190    }
191}
192
193impl<M> PartialEq for ManagedAddress<M>
194where
195    M: ManagedTypeApi,
196{
197    #[inline]
198    fn eq(&self, other: &Self) -> bool {
199        self.bytes == other.bytes
200    }
201}
202
203impl<M> Eq for ManagedAddress<M> where M: ManagedTypeApi {}
204
205impl<M> TopEncode for ManagedAddress<M>
206where
207    M: ManagedTypeApi,
208{
209    #[inline]
210    fn top_encode_or_handle_err<O, H>(&self, output: O, h: H) -> Result<(), H::HandledErr>
211    where
212        O: TopEncodeOutput,
213        H: EncodeErrorHandler,
214    {
215        self.bytes.top_encode_or_handle_err(output, h)
216    }
217}
218
219impl<M> TopDecode for ManagedAddress<M>
220where
221    M: ManagedTypeApi,
222{
223    fn top_decode_or_handle_err<I, H>(input: I, h: H) -> Result<Self, H::HandledErr>
224    where
225        I: TopDecodeInput,
226        H: DecodeErrorHandler,
227    {
228        Ok(ManagedAddress {
229            bytes: ManagedByteArray::top_decode_or_handle_err(input, h)?,
230        })
231    }
232}
233
234impl<M> NestedEncode for ManagedAddress<M>
235where
236    M: ManagedTypeApi,
237{
238    #[inline]
239    fn dep_encode_or_handle_err<O, H>(&self, dest: &mut O, h: H) -> Result<(), H::HandledErr>
240    where
241        O: NestedEncodeOutput,
242        H: EncodeErrorHandler,
243    {
244        self.bytes.dep_encode_or_handle_err(dest, h)
245    }
246}
247
248impl<M> NestedDecode for ManagedAddress<M>
249where
250    M: ManagedTypeApi,
251{
252    fn dep_decode_or_handle_err<I, H>(input: &mut I, h: H) -> Result<Self, H::HandledErr>
253    where
254        I: NestedDecodeInput,
255        H: DecodeErrorHandler,
256    {
257        Ok(ManagedAddress {
258            bytes: ManagedByteArray::dep_decode_or_handle_err(input, h)?,
259        })
260    }
261}
262
263impl<M> TypeAbiFrom<Self> for ManagedAddress<M> where M: ManagedTypeApi {}
264impl<M> TypeAbiFrom<&Self> for ManagedAddress<M> where M: ManagedTypeApi {}
265
266impl<M> TypeAbi for ManagedAddress<M>
267where
268    M: ManagedTypeApi,
269{
270    type Unmanaged = crate::types::heap::Address;
271
272    /// `"Address"` instead of `"array32<u8>"`.
273    fn type_name() -> TypeName {
274        Address::type_name()
275    }
276
277    fn type_name_rust() -> TypeName {
278        "ManagedAddress<$API>".into()
279    }
280}
281
282impl<M: ManagedTypeApi> SCLowerHex for ManagedAddress<M> {
283    fn fmt<F: FormatByteReceiver>(&self, f: &mut F) {
284        SCLowerHex::fmt(&self.bytes, f)
285    }
286}
287
288impl<M: ManagedTypeApi> ManagedAddress<M> {
289    pub fn hex_expr(&self) -> ManagedBuffer<M> {
290        self.bytes.buffer.hex_expr()
291    }
292}
293
294impl<M: ManagedTypeApi> core::fmt::Debug for ManagedAddress<M> {
295    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
296        f.debug_struct("ManagedAddress")
297            .field("handle", &self.bytes.buffer.handle)
298            .field("hex-value", &encode_bytes_as_hex(&self.to_byte_array()))
299            .finish()
300    }
301}
302
303impl<M> TypeAbiFrom<[u8; 32]> for ManagedAddress<M> where M: ManagedTypeApi {}
304
305impl<M> TypeAbiFrom<Address> for ManagedAddress<M> where M: ManagedTypeApi {}
306impl<M> TypeAbiFrom<&Address> for ManagedAddress<M> where M: ManagedTypeApi {}
307impl<M> TypeAbiFrom<ManagedAddress<M>> for Address where M: ManagedTypeApi {}
308impl<M> TypeAbiFrom<&ManagedAddress<M>> for Address where M: ManagedTypeApi {}