Skip to main content

multiversx_sc/types/managed/wrapped/
managed_ref.rs

1use core::{borrow::Borrow, marker::PhantomData, ops::Deref};
2
3use crate::codec::{
4    EncodeErrorHandler, NestedEncode, NestedEncodeOutput, TopEncode, TopEncodeOutput,
5};
6
7use crate::{api::ManagedTypeApi, types::ManagedType};
8
9/// A very efficient reference to a managed type, with copy semantics.
10///
11/// It copies the handle and knows how to deref back.
12pub struct ManagedRef<'a, M, T>
13where
14    M: ManagedTypeApi,
15    T: ManagedType<M>,
16{
17    pub(super) _phantom_m: PhantomData<M>,
18    pub(super) _phantom_t: PhantomData<&'a T>,
19    pub(super) handle: T::OwnHandle,
20}
21
22impl<'a, M, T> ManagedRef<'a, M, T>
23where
24    M: ManagedTypeApi,
25    T: ManagedType<M>,
26{
27    pub fn new(value: &'a T) -> Self {
28        Self {
29            _phantom_m: PhantomData,
30            _phantom_t: PhantomData,
31            handle: value.get_handle(),
32        }
33    }
34
35    /// Will completely disregard lifetimes, use with care.
36    #[doc(hidden)]
37    pub unsafe fn wrap_handle(handle: T::OwnHandle) -> Self {
38        Self {
39            _phantom_m: PhantomData,
40            _phantom_t: PhantomData,
41            handle,
42        }
43    }
44
45    #[doc(hidden)]
46    #[inline]
47    pub fn get_raw_handle_of_ref(self) -> T::OwnHandle {
48        self.handle
49    }
50}
51
52impl<M, T> ManagedRef<'_, M, T>
53where
54    M: ManagedTypeApi,
55    T: ManagedType<M> + Clone,
56{
57    /// Syntactic sugar for dereferencing and cloning the object.
58    pub fn clone_value(&self) -> T {
59        self.deref().clone()
60    }
61}
62
63impl<M, T> ManagedRef<'_, M, T>
64where
65    M: ManagedTypeApi,
66    T: ManagedType<M>,
67{
68    /// Clones the reference itself, not the object contained therein.
69    pub fn clone_ref(&self) -> Self {
70        Self {
71            _phantom_m: PhantomData,
72            _phantom_t: PhantomData,
73            handle: self.handle.clone(),
74        }
75    }
76}
77
78impl<M, T> Deref for ManagedRef<'_, M, T>
79where
80    M: ManagedTypeApi,
81    T: ManagedType<M>,
82{
83    type Target = T;
84
85    #[inline]
86    fn deref(&self) -> &Self::Target {
87        Self::Target::transmute_from_handle_ref(&self.handle)
88    }
89}
90
91impl<M, T> Borrow<T> for ManagedRef<'_, M, T>
92where
93    M: ManagedTypeApi,
94    T: ManagedType<M>,
95{
96    #[inline]
97    fn borrow(&self) -> &T {
98        self.deref()
99    }
100}
101
102impl<M, T> AsRef<T> for ManagedRef<'_, M, T>
103where
104    M: ManagedTypeApi,
105    T: ManagedType<M>,
106{
107    fn as_ref(&self) -> &T {
108        self.deref()
109    }
110}
111
112impl<'a, M, T> From<&'a T> for ManagedRef<'a, M, T>
113where
114    M: ManagedTypeApi,
115    T: ManagedType<M>,
116{
117    #[inline]
118    fn from(value_ref: &'a T) -> Self {
119        Self::new(value_ref)
120    }
121}
122
123impl<M, T> PartialEq for ManagedRef<'_, M, T>
124where
125    M: ManagedTypeApi,
126    T: ManagedType<M> + PartialEq,
127{
128    #[inline]
129    fn eq(&self, other: &Self) -> bool {
130        self.deref() == other.deref()
131    }
132}
133
134impl<M, T> Eq for ManagedRef<'_, M, T>
135where
136    M: ManagedTypeApi,
137    T: ManagedType<M> + PartialEq,
138{
139}
140
141impl<M, T> TopEncode for ManagedRef<'_, M, T>
142where
143    M: ManagedTypeApi,
144    T: ManagedType<M> + TopEncode,
145{
146    #[inline]
147    fn top_encode_or_handle_err<O, H>(&self, output: O, h: H) -> Result<(), H::HandledErr>
148    where
149        O: TopEncodeOutput,
150        H: EncodeErrorHandler,
151    {
152        self.deref().top_encode_or_handle_err(output, h)
153    }
154}
155
156impl<M, T> NestedEncode for ManagedRef<'_, M, T>
157where
158    M: ManagedTypeApi,
159    T: ManagedType<M> + NestedEncode,
160{
161    #[inline]
162    fn dep_encode_or_handle_err<O, H>(&self, dest: &mut O, h: H) -> Result<(), H::HandledErr>
163    where
164        O: NestedEncodeOutput,
165        H: EncodeErrorHandler,
166    {
167        self.deref().dep_encode_or_handle_err(dest, h)
168    }
169}
170
171impl<M, T> core::fmt::Debug for ManagedRef<'_, M, T>
172where
173    M: ManagedTypeApi,
174    T: ManagedType<M> + core::fmt::Debug,
175{
176    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
177        f.debug_tuple("ManagedRef").field(self.deref()).finish()
178    }
179}