multiversx_sc/types/managed/wrapped/
managed_ref_mut.rs

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