rt_ref/
ref_mut.rs

1use std::{
2    cmp::PartialEq,
3    fmt,
4    ops::{Deref, DerefMut},
5};
6
7pub use crate::cell_ref_mut::CellRefMut;
8
9/// Mutable reference to a value.
10pub struct RefMut<'a, V>
11where
12    V: 'a,
13{
14    pub(crate) inner: CellRefMut<'a, V>,
15}
16
17impl<'a, V> fmt::Debug for RefMut<'a, V>
18where
19    V: fmt::Debug + 'a,
20{
21    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
22        let inner: &V = self;
23        f.debug_struct("RefMut").field("inner", inner).finish()
24    }
25}
26
27impl<'a, V> PartialEq for RefMut<'a, V>
28where
29    V: PartialEq + 'a,
30{
31    fn eq(&self, other: &Self) -> bool {
32        let r_self: &V = self;
33        let r_other: &V = other;
34        r_self == r_other
35    }
36}
37
38impl<'a, V> RefMut<'a, V> {
39    pub fn new(inner: CellRefMut<'a, V>) -> Self {
40        Self { inner }
41    }
42}
43
44impl<'a, V> Deref for RefMut<'a, V> {
45    type Target = V;
46
47    fn deref(&self) -> &V {
48        &self.inner
49    }
50}
51
52impl<'a, V> DerefMut for RefMut<'a, V> {
53    fn deref_mut(&mut self) -> &mut V {
54        &mut self.inner
55    }
56}
57
58#[cfg(test)]
59mod tests {
60    use std::{
61        fmt::{self, Write},
62        sync::atomic::AtomicUsize,
63    };
64
65    use crate::CellRefMut;
66
67    use super::RefMut;
68
69    #[test]
70    fn debug_includes_inner_field() -> fmt::Result {
71        let flag = AtomicUsize::new(0);
72        let mut value = A(1);
73        let ref_mut = RefMut::new(CellRefMut {
74            flag: &flag,
75            value: &mut value,
76        });
77
78        let mut debug_string = String::with_capacity(64);
79        write!(&mut debug_string, "{:?}", ref_mut)?;
80        assert_eq!("RefMut { inner: A(1) }", debug_string.as_str());
81
82        Ok(())
83    }
84
85    #[test]
86    fn partial_eq_compares_value() -> fmt::Result {
87        let flag = AtomicUsize::new(0);
88        let mut value = A(1);
89        let mut value_clone = value.clone();
90        let ref_mut = RefMut::new(CellRefMut {
91            flag: &flag,
92            value: &mut value,
93        });
94
95        assert_eq!(
96            RefMut::new(CellRefMut {
97                flag: &flag,
98                value: &mut value_clone,
99            }),
100            ref_mut
101        );
102        assert_ne!(
103            RefMut::new(CellRefMut {
104                flag: &flag,
105                value: &mut A(2),
106            }),
107            ref_mut
108        );
109
110        Ok(())
111    }
112
113    #[test]
114    fn deref_mut_returns_value() -> fmt::Result {
115        let flag = AtomicUsize::new(0);
116        let mut value = A(1);
117        let mut ref_mut = RefMut::new(CellRefMut {
118            flag: &flag,
119            value: &mut value,
120        });
121
122        assert_eq!(
123            RefMut::new(CellRefMut {
124                flag: &flag,
125                value: &mut A(1),
126            }),
127            ref_mut
128        );
129
130        ref_mut.0 = 2;
131
132        assert_eq!(
133            RefMut::new(CellRefMut {
134                flag: &flag,
135                value: &mut A(2),
136            }),
137            ref_mut
138        );
139
140        Ok(())
141    }
142
143    #[derive(Debug, Clone, PartialEq)]
144    struct A(usize);
145}