Skip to main content

multiversx_sc/types/managed/wrapped/
managed_vec_ref.rs

1use crate::types::ManagedVecItem;
2use core::{borrow::Borrow, fmt::Debug, marker::PhantomData, mem::ManuallyDrop, ops::Deref};
3
4/// A reference to a type that implements ManagedVecItem.
5///
6/// Primarily used for preventing any mutability.
7///
8/// The names Ref and ManagedVecRef are interchangeable.
9pub struct Ref<'a, T>
10where
11    T: ManagedVecItem,
12{
13    _phantom: PhantomData<&'a T>, // needed for the lifetime, even though T is present
14    item: ManuallyDrop<T>,
15}
16
17/// The names ManagedVecRef and Ref are interchangeable.
18pub type ManagedVecRef<'a, T> = Ref<'a, T>;
19
20impl<T> Ref<'_, T>
21where
22    T: ManagedVecItem,
23{
24    /// Creates a new ManagedVecRef instance.
25    ///
26    /// ## Safety
27    ///
28    /// The ManagedVecRef object might not drop its content, effectively leading to a leak.
29    pub unsafe fn new(item: T) -> Self {
30        Ref {
31            _phantom: PhantomData,
32            item: ManuallyDrop::new(item),
33        }
34    }
35}
36
37impl<T> Drop for Ref<'_, T>
38where
39    T: ManagedVecItem,
40{
41    fn drop(&mut self) {
42        // TODO: improve
43        unsafe {
44            ManuallyDrop::drop(&mut self.item);
45        }
46    }
47}
48
49impl<T> Deref for Ref<'_, T>
50where
51    T: ManagedVecItem,
52{
53    type Target = T;
54
55    fn deref(&self) -> &Self::Target {
56        &self.item
57    }
58}
59
60impl<T> Borrow<T> for Ref<'_, T>
61where
62    T: ManagedVecItem,
63{
64    fn borrow(&self) -> &T {
65        self.deref()
66    }
67}
68
69impl<T> AsRef<T> for Ref<'_, T>
70where
71    T: ManagedVecItem,
72{
73    fn as_ref(&self) -> &T {
74        self.deref()
75    }
76}
77
78impl<T> Debug for Ref<'_, T>
79where
80    T: ManagedVecItem + Debug,
81{
82    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
83        self.item.deref().fmt(f)
84    }
85}
86
87impl<T1, T2> PartialEq<Ref<'_, T2>> for Ref<'_, T1>
88where
89    T1: ManagedVecItem + PartialEq<T2>,
90    T2: ManagedVecItem,
91{
92    fn eq(&self, other: &Ref<'_, T2>) -> bool {
93        self.deref().eq(other.deref())
94    }
95}