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}