1use std::ops::{DerefMut, IndexMut};
2
3use crate::read::Readable;
4
5#[allow(type_alias_bounds)]
7pub type WritableRef<'a, T: Writable, O = <T as Readable>::Target> = T::Mut<'a, O>;
8
9pub trait Writable: Readable {
35 type Mut<'a, R: ?Sized + 'static>: DerefMut<Target = R>;
37
38 fn map_mut<I: ?Sized, U: ?Sized, F: FnOnce(&mut I) -> &mut U>(
40 ref_: Self::Mut<'_, I>,
41 f: F,
42 ) -> Self::Mut<'_, U>;
43
44 fn try_map_mut<I: ?Sized, U: ?Sized, F: FnOnce(&mut I) -> Option<&mut U>>(
46 ref_: Self::Mut<'_, I>,
47 f: F,
48 ) -> Option<Self::Mut<'_, U>>;
49
50 fn downcast_lifetime_mut<'a: 'b, 'b, T: ?Sized + 'static>(
54 mut_: Self::Mut<'a, T>,
55 ) -> Self::Mut<'b, T>;
56
57 #[track_caller]
59 fn write(&mut self) -> WritableRef<'_, Self> {
60 self.try_write().unwrap()
61 }
62
63 #[track_caller]
65 fn try_write(&mut self) -> Result<WritableRef<'_, Self>, generational_box::BorrowMutError> {
66 self.try_write_unchecked().map(Self::downcast_lifetime_mut)
67 }
68
69 fn try_write_unchecked(
73 &self,
74 ) -> Result<WritableRef<'static, Self>, generational_box::BorrowMutError>;
75
76 #[track_caller]
80 fn write_unchecked(&self) -> WritableRef<'static, Self> {
81 self.try_write_unchecked().unwrap()
82 }
83
84 #[track_caller]
86 fn with_mut<O>(&mut self, f: impl FnOnce(&mut Self::Target) -> O) -> O {
87 f(&mut *self.write())
88 }
89
90 #[track_caller]
92 fn set(&mut self, value: Self::Target)
93 where
94 Self::Target: Sized,
95 {
96 *self.write() = value;
97 }
98
99 #[track_caller]
101 fn toggle(&mut self)
102 where
103 Self::Target: std::ops::Not<Output = Self::Target> + Clone,
104 {
105 self.set(!self.cloned());
106 }
107
108 #[track_caller]
110 fn index_mut<I>(
111 &mut self,
112 index: I,
113 ) -> WritableRef<'_, Self, <Self::Target as std::ops::Index<I>>::Output>
114 where
115 Self::Target: std::ops::IndexMut<I>,
116 {
117 Self::map_mut(self.write(), |v| v.index_mut(index))
118 }
119
120 #[track_caller]
122 fn take(&mut self) -> Self::Target
123 where
124 Self::Target: Default,
125 {
126 self.with_mut(std::mem::take)
127 }
128
129 #[track_caller]
131 fn replace(&mut self, value: Self::Target) -> Self::Target
132 where
133 Self::Target: Sized,
134 {
135 self.with_mut(|v| std::mem::replace(v, value))
136 }
137}
138
139pub trait WritableOptionExt<T: 'static>: Writable<Target = Option<T>> {
141 #[track_caller]
143 fn get_or_insert(&mut self, default: T) -> WritableRef<'_, Self, T> {
144 self.get_or_insert_with(|| default)
145 }
146
147 #[track_caller]
149 fn get_or_insert_with(&mut self, default: impl FnOnce() -> T) -> WritableRef<'_, Self, T> {
150 let is_none = self.read().is_none();
151 if is_none {
152 self.with_mut(|v| *v = Some(default()));
153 Self::map_mut(self.write(), |v| v.as_mut().unwrap())
154 } else {
155 Self::map_mut(self.write(), |v| v.as_mut().unwrap())
156 }
157 }
158
159 #[track_caller]
161 fn as_mut(&mut self) -> Option<WritableRef<'_, Self, T>> {
162 Self::try_map_mut(self.write(), |v: &mut Option<T>| v.as_mut())
163 }
164}
165
166impl<T, W> WritableOptionExt<T> for W
167where
168 T: 'static,
169 W: Writable<Target = Option<T>>,
170{
171}
172
173pub trait WritableVecExt<T: 'static>: Writable<Target = Vec<T>> {
175 #[track_caller]
177 fn push(&mut self, value: T) {
178 self.with_mut(|v| v.push(value))
179 }
180
181 #[track_caller]
183 fn pop(&mut self) -> Option<T> {
184 self.with_mut(|v| v.pop())
185 }
186
187 #[track_caller]
189 fn insert(&mut self, index: usize, value: T) {
190 self.with_mut(|v| v.insert(index, value))
191 }
192
193 #[track_caller]
195 fn remove(&mut self, index: usize) -> T {
196 self.with_mut(|v| v.remove(index))
197 }
198
199 #[track_caller]
201 fn clear(&mut self) {
202 self.with_mut(|v| v.clear())
203 }
204
205 #[track_caller]
207 fn extend(&mut self, iter: impl IntoIterator<Item = T>) {
208 self.with_mut(|v| v.extend(iter))
209 }
210
211 #[track_caller]
213 fn truncate(&mut self, len: usize) {
214 self.with_mut(|v| v.truncate(len))
215 }
216
217 #[track_caller]
219 fn swap_remove(&mut self, index: usize) -> T {
220 self.with_mut(|v| v.swap_remove(index))
221 }
222
223 #[track_caller]
225 fn retain(&mut self, f: impl FnMut(&T) -> bool) {
226 self.with_mut(|v| v.retain(f))
227 }
228
229 #[track_caller]
231 fn split_off(&mut self, at: usize) -> Vec<T> {
232 self.with_mut(|v| v.split_off(at))
233 }
234
235 #[track_caller]
237 fn get_mut(&mut self, index: usize) -> Option<WritableRef<'_, Self, T>> {
238 Self::try_map_mut(self.write(), |v: &mut Vec<T>| v.get_mut(index))
239 }
240
241 #[track_caller]
243 fn iter_mut(&mut self) -> WritableValueIterator<'_, Self>
244 where
245 Self: Sized + Clone,
246 {
247 WritableValueIterator {
248 index: 0,
249 value: self,
250 }
251 }
252}
253
254pub struct WritableValueIterator<'a, R> {
256 index: usize,
257 value: &'a mut R,
258}
259
260impl<'a, T: 'static, R: Writable<Target = Vec<T>>> Iterator for WritableValueIterator<'a, R> {
261 type Item = WritableRef<'a, R, T>;
262
263 fn next(&mut self) -> Option<Self::Item> {
264 let index = self.index;
265 self.index += 1;
266 R::try_map_mut(
267 self.value.try_write_unchecked().unwrap(),
268 |v: &mut Vec<T>| v.get_mut(index),
269 )
270 .map(R::downcast_lifetime_mut)
271 }
272}
273
274impl<T, W> WritableVecExt<T> for W
275where
276 T: 'static,
277 W: Writable<Target = Vec<T>>,
278{
279}