1use std::{
2 cmp::PartialEq,
3 fmt,
4 ops::{Deref, DerefMut},
5};
6
7pub use crate::cell_ref_mut::CellRefMut;
8
9pub 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}