shipyard/
mut.rs

1use crate::tracking::TrackingTimestamp;
2
3/// Tracks component modification.
4pub struct Mut<'a, T: ?Sized> {
5    pub(crate) flag: Option<&'a mut TrackingTimestamp>,
6    pub(crate) current: TrackingTimestamp,
7    pub(crate) data: &'a mut T,
8}
9
10impl<'a, T: ?Sized> Mut<'a, T> {
11    /// Makes a new [`Mut`], the component will not be flagged if its modified inside `f`.
12    ///
13    /// This is an associated function that needs to be used as `Mut::map(...)`. A method would interfere with methods of the same name used through Deref.
14    pub fn map<U: ?Sized, F: FnOnce(&mut T) -> &mut U>(orig: Self, f: F) -> Mut<'a, U> {
15        Mut {
16            flag: orig.flag,
17            current: orig.current,
18            data: f(orig.data),
19        }
20    }
21}
22
23impl<T: ?Sized> core::ops::Deref for Mut<'_, T> {
24    type Target = T;
25
26    #[inline]
27    fn deref(&self) -> &Self::Target {
28        self.data
29    }
30}
31
32impl<T: ?Sized> core::ops::DerefMut for Mut<'_, T> {
33    #[inline]
34    fn deref_mut(&mut self) -> &mut Self::Target {
35        if let Some(flag) = &mut self.flag {
36            **flag = self.current;
37        }
38
39        self.data
40    }
41}
42
43impl<T: ?Sized> AsRef<T> for Mut<'_, T> {
44    #[inline]
45    fn as_ref(&self) -> &T {
46        self.data
47    }
48}
49
50impl<T: ?Sized> AsMut<T> for Mut<'_, T> {
51    #[inline]
52    fn as_mut(&mut self) -> &mut T {
53        if let Some(flag) = &mut self.flag {
54            **flag = self.current;
55        }
56
57        self.data
58    }
59}
60
61impl<T: ?Sized + core::fmt::Debug> core::fmt::Debug for Mut<'_, T> {
62    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
63        self.data.fmt(f)
64    }
65}