veccell/vecrefmut.rs
1use super::*;
2
3// Lets us safely destructure VecRefMut while implementing the Drop logic
4struct VecRefMutBorrow<'a>(&'a Cell<Option<usize>>);
5
6/// Wraps a mutably borrowed value from a [`VecCell`].
7pub struct VecRefMut<'a, T: ?Sized> {
8 mut_borrow: VecRefMutBorrow<'a>,
9 value: &'a mut T,
10}
11
12impl<'a, T: ?Sized> VecRefMut<'a, T> {
13 /// # Safety
14 ///
15 /// If this function returns Some(ref), then there are no mutable borrows of ∀x, vec.inner[x]:
16 /// by contradiction, let `B: 'b` be a mutable borrow of lifetime `'b`. By conjunction on (IV):
17 /// - either `B` had exclusive access, in which case calling `VecCell::borrow_mut` is UB
18 /// - either `B` was obtained from a guard `VecRefMut<'c>`, in which case `'c: 'b` and `vec.mut_borrow.is_some()`, which contradicts our assertion
19 ///
20 /// - The invariant (I) is upheld by the first assertion.
21 /// - The invariant (II) is upheld by this function, as it sets `vec.mut_borrow` to `Some(index)`.
22 pub(crate) fn new(vec: &'a VecCell<T>, index: usize) -> Option<Self>
23 where
24 T: Sized
25 {
26 if vec.borrows.get() > 0 || vec.mut_borrow.get().is_some() {
27 return None
28 }
29
30 if index >= vec.len() {
31 return None
32 }
33
34 vec.mut_borrow.set(Some(index));
35
36 Some(Self {
37 mut_borrow: VecRefMutBorrow(&vec.mut_borrow),
38 value: unsafe {
39 vec.get_mut_unchecked(index)
40 }
41 })
42 }
43
44 /// Returns an immutable reference to the borrowed value.
45 /// The reference may not outlive this `VecRefMut` instance.
46 ///
47 /// # Example
48 ///
49 /// ```
50 /// # use veccell::*;
51 /// let mut vec: VecCell<String> = VecCell::new();
52 ///
53 /// vec.push(String::from("hello"));
54 /// vec.push(String::from("world"));
55 ///
56 /// let guard = vec.borrow_mut(0).unwrap();
57 /// assert_eq!(guard.get(), "hello");
58 /// ```
59 pub fn get(&self) -> &T {
60 &*self.value
61 }
62
63 /// Transforms a `VecRefMut<'_, T>` into a `VecRefMut<'_, U>` from a function that maps `&mut T` to `&mut U`.
64 ///
65 /// This function does not use `self` and must be called explicitly via `VecRefMut::map(value, function)`.
66 ///
67 /// # Examples
68 ///
69 /// ```
70 /// # use veccell::*;
71 /// fn return_favorite_value_mut<'a>(array: &'a VecCell<Vec<u8>>) -> VecRefMut<'a, u8> {
72 /// VecRefMut::map(array.borrow_mut(42).unwrap(), |vec| &mut vec[7])
73 /// }
74 /// ```
75 pub fn map<'b, U: ?Sized, F>(original: VecRefMut<'b, T>, f: F) -> VecRefMut<'b, U>
76 where
77 F: FnOnce(&mut T) -> &mut U
78 {
79 let VecRefMut { value, mut_borrow } = original;
80 VecRefMut {
81 value: f(value),
82 mut_borrow
83 }
84 }
85
86 /// Variant of [`VecRefMut::map`], where the callback (`f`) may fail.
87 ///
88 /// `f` must return a `Result`; if it returns `Ok(x)`, then `try_map` returns `Ok(VecRefMut(x))`.
89 /// Otherwise, it returns `Err(err)`.
90 pub fn try_map<'b, U: ?Sized, F, E>(original: VecRefMut<'b, T>, f: F) -> Result<VecRefMut<'b, U>, E>
91 where
92 F: FnOnce(&mut T) -> Result<&mut U, E>
93 {
94 let VecRefMut { value, mut_borrow } = original;
95 Ok(VecRefMut {
96 value: f(value)?,
97 mut_borrow: mut_borrow
98 })
99 }
100}
101
102impl<'a, T: ?Sized> Deref for VecRefMut<'a, T> {
103 type Target = T;
104
105 // SAFETY: Upholds invariant (IV)
106 fn deref(&self) -> &Self::Target {
107 self.value
108 }
109}
110
111impl<'a, T: ?Sized> DerefMut for VecRefMut<'a, T> {
112 // SAFETY: Upholds invariant (IV)
113 fn deref_mut(&mut self) -> &mut Self::Target {
114 self.value
115 }
116}
117
118impl<'a> Drop for VecRefMutBorrow<'a> {
119 #[inline]
120 fn drop(&mut self) {
121 debug_assert!(self.0.get().is_some());
122 self.0.set(None);
123 }
124}
125
126
127impl<'a, T: Debug + ?Sized> Debug for VecRefMut<'a, T> {
128 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129 f.debug_tuple("VecRefMut")
130 .field(&self.value)
131 .finish()
132 }
133}
134
135impl<'a, T: Display + ?Sized> Display for VecRefMut<'a, T> {
136 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
137 <T as Display>::fmt(&self.value, f)
138 }
139}
140
141impl<'a, T: PartialEq + ?Sized> PartialEq for VecRefMut<'a, T> {
142 fn eq(&self, other: &Self) -> bool {
143 self.get() == other.get()
144 }
145}
146
147impl<'a, T: PartialEq + ?Sized> PartialEq<T> for VecRefMut<'a, T> {
148 fn eq(&self, other: &T) -> bool {
149 self.get() == other
150 }
151}