duat_core/data/
rw.rs

1use std::{
2    any::TypeId,
3    sync::{
4        Arc,
5        atomic::{AtomicUsize, Ordering},
6    },
7};
8
9use super::{Data, RoData, RwLock, RwLockReadGuard, RwLockWriteGuard, private::InnerData};
10
11/// A read write shared reference to data
12pub struct RwData<T: ?Sized + 'static> {
13    // The `Box` is to allow for downcasting.
14    pub(super) data: Arc<RwLock<T>>,
15    pub(super) cur_state: Arc<AtomicUsize>,
16    read_state: AtomicUsize,
17    pub(super) type_id: TypeId,
18}
19
20impl<T> RwData<T> {
21    /// Returns a new instance of a [`RwData`], assuming that it is
22    /// sized.
23    ///
24    /// This has to be sized because of some Rust limitations, as you
25    /// can`t really pass an unsized argument to a function (for now).
26    /// If you're looking to store unsized types (`dyn Trait`,
27    /// `\[Type\]`, etc) on an [`RwData`], see
28    /// [`RwData::new_unsized`].
29    pub fn new(data: T) -> Self {
30        Self {
31            data: Arc::new(RwLock::new(data)),
32            cur_state: Arc::new(AtomicUsize::new(1)),
33            read_state: AtomicUsize::new(1),
34            type_id: TypeId::of::<T>(),
35        }
36    }
37}
38
39impl<T: ?Sized> RwData<T> {
40    /// Returns a new instance of [`RwData`], assuming that it is
41    /// unsized.
42    ///
43    /// This method is only required if you're dealing with types that
44    /// may not be [`Sized`] (`dyn Trait`, `[Type]`, etc). If the type
45    /// in question is sized, use [`RwData::new`] instead.
46    pub fn new_unsized<SizedT: 'static>(data: Arc<RwLock<T>>) -> Self {
47        // It's 1 here so that any `RoState`s created from this will have
48        // `has_changed()` return `true` at least once, by copying the
49        // second value - 1.
50        Self {
51            data,
52            cur_state: Arc::new(AtomicUsize::new(1)),
53            read_state: AtomicUsize::new(1),
54            type_id: TypeId::of::<SizedT>(),
55        }
56    }
57
58    /// Blocking reference to the information
59    ///
60    /// Also makes it so that [`has_changed`] returns `false`.
61    ///
62    /// # Examples
63    ///
64    /// Since this is a blocking read, the thread will hault while the
65    /// data is being written to:
66    /// ```rust
67    /// # use std::{thread, time::{Duration, Instant}};
68    /// # use duat_core::data::{RoData, RwData};
69    /// let read_write_data = RwData::new("☹️");
70    /// let read_only_data = RoData::from(&read_write_data);
71    /// let instant = Instant::now();
72    /// thread::scope(|scope| {
73    ///     scope.spawn(|| {
74    ///         let mut read_write = read_write_data.write();
75    ///         // Supposedly long computations.
76    ///         thread::sleep(Duration::from_millis(150));
77    ///         *read_write = "☺️";
78    ///     });
79    ///
80    ///     // Just making sure that the read happens slightly after the write.
81    ///     thread::sleep(Duration::from_millis(10));
82    ///
83    ///     let read_only = read_only_data.read();
84    ///     let time_elapsed = Instant::now().duration_since(instant);
85    ///     assert!(time_elapsed >= Duration::from_millis(100));
86    ///     assert!(*read_only == "☺️");
87    /// });
88    /// ```
89    /// Note that other reads will **NOT** block reading in this way,
90    /// only writes:
91    /// ```rust
92    /// # use std::{thread, time::{Duration, Instant}};
93    /// # use duat_core::data::{RoData, RwData};
94    /// let read_write_data = RwData::new("☹️");
95    /// let read_only_data = RoData::from(&read_write_data);
96    /// let instant = Instant::now();
97    /// thread::scope(|scope| {
98    ///     scope.spawn(|| {
99    ///         let read_only = read_write_data.read();
100    ///         // The thread hangs, but reading is still possible.
101    ///         thread::sleep(Duration::from_millis(100));
102    ///     });
103    ///
104    ///     // Just making sure that this read happens slightly after the last one.
105    ///     thread::sleep(Duration::from_millis(1));
106    ///
107    ///     let read_only = read_only_data.read();
108    ///     let time_elapsed = Instant::now().duration_since(instant);
109    ///     assert!(time_elapsed < Duration::from_millis(100));
110    /// });
111    /// ```
112    /// [`has_changed`]: Self::has_changed
113    pub fn read(&self) -> RwLockReadGuard<'_, T> {
114        let cur_state = self.cur_state().load(Ordering::Acquire);
115        self.read_state().store(cur_state, Ordering::Release);
116        self.data()
117    }
118
119    /// Blocking inspection of the inner data
120    ///
121    /// Also makes it so that [`has_changed`] returns `false`.
122    ///
123    /// # Examples
124    ///
125    /// This method is useful if you want to scope the reading, or
126    /// need to drop the reference quickly, so it can be written to.
127    ///
128    /// You can do this:
129    /// ```rust
130    /// # use duat_core::data::{RoData, RwData};
131    /// # fn add_to_count(count: &mut usize) {}
132    /// # fn new_count() -> usize {
133    /// #     0
134    /// # }
135    /// let count = RwData::new(31);
136    /// let count_reader = RoData::from(&count);
137    ///
138    /// // The read write counterpart to `inspect`.
139    /// count.mutate(|count| {
140    ///     *count += 5;
141    ///     add_to_count(count)
142    /// });
143    ///
144    /// count_reader.inspect(|count| { /* reading operations */ });
145    ///
146    /// *count.write() = new_count();
147    /// ```
148    /// Instead of this:
149    /// ```rust
150    /// # use duat_core::data::{RoData, RwData};
151    /// # fn add_to_count(count: &mut usize) {}
152    /// # fn new_count() -> usize {
153    /// #     0
154    /// # }
155    /// let count = RwData::new(31);
156    /// let count_reader = RoData::from(&count);
157    ///
158    /// // The read write counterpart to `inspect`.
159    /// let mut count_write = count.write();
160    /// *count_write += 5;
161    /// add_to_count(&mut *count_write);
162    /// drop(count_write);
163    ///
164    /// let count_read = count_reader.read();
165    /// // reading operations
166    /// drop(count_read);
167    ///
168    /// *count.write() = new_count();
169    /// ```
170    /// Or this:
171    /// ```rust
172    /// # use duat_core::data::{RoData, RwData};
173    /// # fn add_to_count(count: &mut usize) {}
174    /// # fn new_count() -> usize {
175    /// #     0
176    /// # }
177    /// let count = RwData::new(31);
178    /// let count_reader = RoData::from(&count);
179    ///
180    /// // The read write counterpart to `inspect`.
181    /// {
182    ///     let mut count = count.write();
183    ///     *count += 5;
184    ///     add_to_count(&mut count)
185    /// }
186    ///
187    /// {
188    ///     let count = count.read();
189    ///     // reading operations
190    /// }
191    ///
192    /// *count.write() = new_count();
193    /// ```
194    /// [`has_changed`]: Self::has_changed
195    pub fn inspect<U>(&self, f: impl FnOnce(&T) -> U) -> U {
196        let cur_state = self.cur_state().load(Ordering::Acquire);
197        self.read_state().store(cur_state, Ordering::Release);
198        f(&self.data())
199    }
200
201    /// Non blocking reference to the information
202    ///
203    /// If successful, also makes it so that [`has_changed`] returns
204    /// `false`.
205    ///
206    /// # Examples
207    ///
208    /// Unlike [`read`], can fail to return a reference to the
209    /// underlying data:
210    /// ```rust
211    /// # use std::{sync::TryLockError};
212    /// # use duat_core::data::RwData;
213    /// let new_data = RwData::new("hello 👋");
214    ///
215    /// let mut blocking_write = new_data.write();
216    /// *blocking_write = "bye 👋";
217    ///
218    /// let try_read = new_data.try_read();
219    /// assert!(matches!(try_read, None));
220    /// ```
221    ///
222    /// [`has_changed`]: Self::has_changed
223    /// [`read`]: Self::read
224    pub fn try_read(&self) -> Option<RwLockReadGuard<'_, T>> {
225        self.try_data().inspect(|_| {
226            let cur_state = self.cur_state().load(Ordering::Acquire);
227            self.read_state().store(cur_state, Ordering::Release);
228        })
229    }
230
231    /// Non blocking inspection of the inner data
232    ///
233    /// If successful, also makes it so that [`has_changed`] returns
234    /// `false`.
235    ///
236    /// # Examples
237    ///
238    /// Unlike [`inspect`], can fail to return a reference to the
239    /// underlying data:
240    /// ```rust
241    /// # use std::sync::TryLockError;
242    /// # use duat_core::data::RwData;
243    /// let new_data = RwData::new("hello 👋");
244    ///
245    /// let try_inspect = new_data.mutate(|blocking_mutate| {
246    ///     *blocking_mutate = "bye 👋";
247    ///
248    ///     new_data.try_inspect(|try_inspect| *try_inspect == "bye 👋")
249    /// });
250    ///
251    /// assert!(matches!(try_inspect, None));
252    /// ```
253    ///
254    /// [`has_changed`]: Self::has_changed
255    /// [`inspect`]: Self::inspect
256    pub fn try_inspect<U>(&self, f: impl FnOnce(&T) -> U) -> Option<U> {
257        self.try_data().map(|data| {
258            let cur_state = self.cur_state().load(Ordering::Acquire);
259            self.read_state().store(cur_state, Ordering::Release);
260            f(&data)
261        })
262    }
263
264    /// Whether or not it has changed since it was last read
265    ///
266    /// A "change" is defined as any time the methods [`write`],
267    /// [`mutate`], [`try_write`], or [`try_mutate`], are called on an
268    /// [`RwData`]. Once `has_changed` is called, the data will be
269    /// considered unchanged since the last `has_changed` call, for
270    /// that specific instance of a [`Data`].
271    ///
272    /// When first creating a [`Data`] type, `has_changed`
273    /// will return `false`;
274    ///
275    /// # Examples
276    /// ```rust
277    /// use duat_core::data::{RoData, RwData};
278    /// let new_data = RwData::new("Initial text");
279    /// assert!(!new_data.has_changed());
280    ///
281    /// let first_reader = RoData::from(&new_data);
282    ///
283    /// *new_data.write() = "Final text";
284    ///
285    /// let second_reader = RoData::from(&new_data);
286    ///
287    /// assert!(first_reader.has_changed());
288    /// assert!(!second_reader.has_changed());
289    /// ```
290    ///
291    /// [`write`]: RwData::write
292    /// [`mutate`]: RwData::mutate
293    /// [`try_write`]: RwData::try_write
294    /// [`try_mutate`]: RwData::try_mutate
295    pub fn has_changed(&self) -> bool {
296        let cur_state = self.cur_state().load(Ordering::Relaxed);
297        let read_state = self.read_state().swap(cur_state, Ordering::Relaxed);
298        cur_state > read_state
299    }
300
301    /// Returns `true` if both [`Data`]s point to the same
302    /// data.
303    ///
304    /// # Examples
305    /// ```rust
306    /// # use duat_core::data::{RwData};
307    /// let data_1 = RwData::new(false);
308    /// let data_1_clone = data_1.clone();
309    ///
310    /// let data_2 = RwData::new(true);
311    ///
312    /// assert!(data_1.ptr_eq(&data_1_clone));
313    /// assert!(!data_1.ptr_eq(&data_2));
314    /// ```
315    pub fn ptr_eq<U: ?Sized>(&self, other: &(impl Data<U> + ?Sized)) -> bool {
316        Arc::as_ptr(self.cur_state()) == Arc::as_ptr(other.cur_state())
317    }
318
319    /// Blocking mutable reference to the information
320    ///
321    /// Also makes it so that [`has_changed`] returns true for
322    /// `self` or any of its clones, be they [`RoData`] or
323    /// [`RwData`].
324    ///
325    /// # Safety
326    ///
327    /// Since this is a blocking function, you should be careful about
328    /// the prevention of deadlocks, one of the few unsafe aspects of
329    /// code that Rust doesn't prevent.
330    ///
331    /// As an example, this code will deadlock indefinitely:
332    /// ```no_run
333    /// # use std::{mem, thread, time::Duration};
334    /// # use duat_core::data::RwData;
335    /// let data_1 = RwData::new('😟');
336    /// let data_2 = RwData::new('😭');
337    ///
338    /// thread::scope(|scope| {
339    ///     scope.spawn(|| {
340    ///         let mut data_1 = data_1.write();
341    ///         thread::sleep(Duration::from_millis(100));
342    ///         let mut data_2 = data_2.write();
343    ///         mem::swap(&mut data_1, &mut data_2);
344    ///     });
345    ///
346    ///     scope.spawn(|| {
347    ///         let mut data_2 = data_2.write();
348    ///         thread::sleep(Duration::from_millis(100));
349    ///         let mut data_1 = data_1.write();
350    ///         mem::swap(&mut data_1, &mut data_2);
351    ///     });
352    /// });
353    /// ```
354    /// In general, try not to juggle multiple `&mut` handles to
355    /// [`RwData`]s. A good way of doing that is the
356    /// [`RwData::mutate`] method, which makes it very explicit when a
357    /// specific handle will be dropped, mitigating the possibility of
358    /// deadlocks.
359    ///
360    ///
361    /// [`has_changed`]: Data::has_changed
362    pub fn write(&self) -> ReadWriteGuard<T> {
363        let guard = self.data.write();
364        ReadWriteGuard { guard, cur_state: &self.cur_state }
365    }
366
367    /// Non Blocking mutable reference to the information
368    ///
369    /// Also makes it so that [`has_changed`] returns true for
370    /// `self` or any of its clones, be they [`RoData`] or
371    /// [`RwData`].
372    ///
373    /// # Safety
374    ///
375    /// Unlike [`RwData::write`], this method cannot cause deadlocks,
376    /// returning an [`Err`] instead.
377    /// ```
378    /// # use std::{mem, thread, time::Duration};
379    /// # use duat_core::data::RwData;
380    /// let data_1 = RwData::new('😀');
381    /// let data_2 = RwData::new('😁');
382    ///
383    /// thread::scope(|scope| {
384    ///     scope.spawn(|| {
385    ///         let mut data_1 = data_1.try_write();
386    ///         thread::sleep(Duration::from_millis(100));
387    ///         let mut data_2 = data_2.try_write();
388    ///         if let (Some(mut data_1), Some(mut data_2)) = (data_1, data_2) {
389    ///             mem::swap(&mut data_1, &mut data_2);
390    ///         }
391    ///     });
392    ///
393    ///     scope.spawn(|| {
394    ///         let mut data_2 = data_2.try_write();
395    ///         thread::sleep(Duration::from_millis(100));
396    ///         let mut data_1 = data_1.try_write();
397    ///         if let (Some(mut data_1), Some(mut data_2)) = (data_1, data_2) {
398    ///             mem::swap(&mut data_1, &mut data_2);
399    ///         }
400    ///     });
401    /// });
402    ///
403    /// // Two swaps will happen.
404    /// assert_eq!(*data_1.read(), '😀');
405    /// assert_eq!(*data_2.read(), '😁');
406    /// ```
407    /// The downside is that you may not want it to fail ever, in
408    /// which case, you should probably use [`RwData::write`].
409    ///
410    /// [`has_changed`]: Data::has_changed
411    pub fn try_write(&self) -> Option<ReadWriteGuard<'_, T>> {
412        self.data
413            .try_write()
414            .map(|guard| ReadWriteGuard { guard, cur_state: &self.cur_state })
415    }
416
417    /// Blocking mutation of the inner data
418    ///
419    /// Also makes it so that [`has_changed`] returns true for
420    /// `self` or any of its clones, be they [`RoData`] or
421    /// [`RwData`].
422    ///
423    /// # Safety
424    ///
425    /// This method "technically" has the same problems as
426    /// [`RwData::write`], where you can deadlock by calling it on
427    /// multiple instances of [`RwData`], but it makes this much more
428    /// explicit:
429    /// ```no_run
430    /// # use std::{mem, thread, time::Duration};
431    /// # use duat_core::data::RwData;
432    /// let data_1 = RwData::new('😟');
433    /// let data_2 = RwData::new('😭');
434    ///
435    /// thread::scope(|scope| {
436    ///     scope.spawn(|| {
437    ///         data_1.mutate(|data_1| {
438    ///             thread::sleep(Duration::from_millis(100));
439    ///             let mut data_2 = data_2.write();
440    ///             mem::swap(data_1, &mut *data_2);
441    ///         });
442    ///     });
443    ///
444    ///     scope.spawn(|| {
445    ///         data_2.mutate(|data_2| {
446    ///             thread::sleep(Duration::from_millis(100));
447    ///             let mut data_1 = data_1.write();
448    ///             mem::swap(&mut *data_1, data_2);
449    ///         });
450    ///     });
451    /// });
452    /// ```
453    /// Generally, you should favor this method for longer functions
454    /// in which the data is only needed for a short time.
455    ///
456    /// [`has_changed`]: Data::has_changed
457    pub fn mutate<R>(&self, f: impl FnOnce(&mut T) -> R) -> R {
458        f(&mut self.write().guard)
459    }
460
461    /// Non blocking mutation of the inner data
462    ///
463    /// Also makes it so that [`has_changed`] returns true for
464    /// `self` or any of its clones, be they [`RoData`] or
465    /// [`RwData`].
466    ///
467    /// # Safety
468    ///
469    /// Much like [`RwData::try_write`], this also can't deadlock,
470    /// failing instead. Generally, you should use this method only
471    /// when you are fine with not writing the data.
472    ///
473    /// [`has_changed`]: Data::has_changed
474    pub fn try_mutate<R>(&self, f: impl FnOnce(&mut T) -> R) -> Option<R> {
475        let res = self.try_write();
476        res.map(|mut data| f(&mut *data))
477    }
478
479    /// Blocking reference to the information
480    ///
481    /// Unlike [`read`], *DOES NOT* make it so
482    /// [`has_changed`] returns `false`.
483    ///
484    /// This method should only be used in very specific
485    /// circumstances, such as when multiple owners have nested
486    /// [`RwData`]s, thus referencing the same inner [`RwData`], in
487    /// a way that reading from one point would interfere in the
488    /// update detection of the other point.
489    ///
490    /// [`read`]: Self::read,
491    /// [`has_changed`]: Self::has_changed
492    pub(crate) fn raw_read(&self) -> RwLockReadGuard<'_, T> {
493        self.data()
494    }
495
496    /// Returns `true` if the data is of the concrete type `T`
497    ///
498    /// # Examples
499    ///
500    /// You may want this method if you're storing a list of
501    /// [`RwData<dyn Trait>`], and want to know, at runtime, what type
502    /// each element is:
503    /// ```rust
504    /// # use std::{any::Any, fmt::Display, sync::Arc};
505    /// # use duat_core::data::{RwData, RwLock};
506    /// let list: [RwData<dyn Display>; 3] = [
507    ///     RwData::new_unsized::<String>(Arc::new(RwLock::new(String::from(
508    ///         "I can show you the world",
509    ///     )))),
510    ///     RwData::new_unsized::<String>(Arc::new(RwLock::new(String::from(
511    ///         "Shining, shimmering, splendid",
512    ///     )))),
513    ///     RwData::new_unsized::<char>(Arc::new(RwLock::new('🧞'))),
514    /// ];
515    ///
516    /// assert!(list[0].data_is::<String>());
517    /// assert!(list[1].data_is::<String>());
518    /// assert!(list[2].data_is::<char>());
519    /// ```
520    ///
521    /// [`RwData<dyn Trait>`]: RwData
522    pub fn data_is<U: ?Sized + 'static>(&self) -> bool {
523        self.type_id == TypeId::of::<U>()
524    }
525
526    /// Tries to downcast to a concrete type
527    ///
528    /// # Examples
529    ///
530    /// You may want this method if you're storing a list of
531    /// [`RwData<dyn Trait>`], and want to know, at runtime, what type
532    /// each element is:
533    /// ```rust
534    /// # use std::{fmt::Display, sync::Arc};
535    /// # use duat_core::data::{RwData, RwLock};
536    /// let list: [RwData<dyn Display>; 3] = [
537    ///     RwData::new_unsized::<String>(Arc::new(RwLock::new(String::from(
538    ///         "I can show you the world",
539    ///     )))),
540    ///     RwData::new_unsized::<String>(Arc::new(RwLock::new(String::from(
541    ///         "Shining, shimmering, splendid",
542    ///     )))),
543    ///     RwData::new_unsized::<char>(Arc::new(RwLock::new('🧞'))),
544    /// ];
545    ///
546    /// let maybe_char = list[2].clone().try_downcast::<char>();
547    /// assert!(maybe_char.is_some());
548    /// *maybe_char.unwrap().write() = '👳';
549    ///
550    /// let maybe_string = list[0].clone().try_downcast::<char>();
551    /// assert!(maybe_string.is_none());
552    /// ```
553    /// If you don't need to write to the data, consider using
554    /// [`RwData::inspect_as`]. If you only need to know if the type
555    /// matches, consider using [`RwData::data_is`].
556    ///
557    /// [`RwData<dyn Trait>`]: RwData
558    pub fn try_downcast<U: 'static>(&self) -> Option<RwData<U>> {
559        if self.data_is::<U>() {
560            let Self { data, cur_state, read_state, .. } = self.clone();
561            let ptr = Arc::into_raw(data);
562            let data = unsafe { Arc::from_raw(ptr.cast()) };
563            Some(RwData {
564                data,
565                cur_state,
566                read_state,
567                type_id: self.type_id,
568            })
569        } else {
570            None
571        }
572    }
573
574    /// Blocking inspection of the inner data
575    ///
576    /// # Examples
577    ///
578    /// You may want this method if you're storing a list of
579    /// [`RwData<dyn Trait>`], and want to know, at runtime, what type
580    /// each element is:
581    /// ```rust
582    /// # use std::{any::Any, fmt::Display, sync::Arc};
583    /// # use duat_core::data::{RwData, RwLock};
584    /// let list: [RwData<dyn Display>; 3] = [
585    ///     RwData::new_unsized::<String>(Arc::new(RwLock::new(String::from(
586    ///         "I can show you the world",
587    ///     )))),
588    ///     RwData::new_unsized::<String>(Arc::new(RwLock::new(String::from(
589    ///         "Shining, shimmering, splendid",
590    ///     )))),
591    ///     RwData::new_unsized::<char>(Arc::new(RwLock::new('🧞'))),
592    /// ];
593    ///
594    /// assert!(matches!(
595    ///     list[2].inspect_as::<char, usize>(|char| char.len_utf8()),
596    ///     Some(4)
597    /// ));
598    /// assert!(matches!(
599    ///     list[1].inspect_as::<char, char>(|char| char.to_ascii_uppercase()),
600    ///     None
601    /// ));
602    /// ```
603    ///
604    /// [`RwData<dyn Trait>`]: RwData
605    pub fn inspect_as<U: 'static, R>(&self, f: impl FnOnce(&U) -> R) -> Option<R> {
606        (self.data_is::<U>()).then(|| {
607            let ptr = Arc::as_ptr(&self.data);
608            let cast = unsafe { ptr.cast::<RwLock<U>>().as_ref().unwrap() };
609
610            self.read_state
611                .store(self.cur_state.load(Ordering::Acquire), Ordering::Release);
612
613            f(&cast.read())
614        })
615    }
616
617    pub fn mutate_as<U: 'static, R>(&self, f: impl FnOnce(&mut U) -> R) -> Option<R> {
618        (self.data_is::<U>()).then(|| {
619            let ptr = Arc::as_ptr(&self.data);
620            let cast = unsafe { ptr.cast::<RwLock<U>>().as_ref().unwrap() };
621
622            self.read_state
623                .store(self.cur_state.load(Ordering::Acquire), Ordering::Release);
624
625            let mut guard = cast.write();
626            f(&mut guard)
627        })
628    }
629
630    pub(crate) fn raw_write(&self) -> RwLockWriteGuard<'_, T> {
631        self.data.write()
632    }
633}
634
635impl<T: ?Sized + std::fmt::Debug> std::fmt::Debug for RwData<T> {
636    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
637        std::fmt::Debug::fmt(&*self.data.read(), f)
638    }
639}
640
641impl<T: ?Sized> Clone for RwData<T> {
642    fn clone(&self) -> Self {
643        Self {
644            data: self.data.clone(),
645            cur_state: self.cur_state.clone(),
646            read_state: AtomicUsize::new(self.cur_state.load(Ordering::Relaxed) - 1),
647            type_id: self.type_id,
648        }
649    }
650}
651
652impl<T: Default> Default for RwData<T> {
653    fn default() -> Self {
654        Self {
655            data: Arc::new(RwLock::new(T::default())),
656            cur_state: Arc::new(AtomicUsize::new(1)),
657            read_state: AtomicUsize::new(1),
658            type_id: TypeId::of::<T>(),
659        }
660    }
661}
662
663impl<T: ?Sized> InnerData<T> for RwData<T> {
664    fn data(&self) -> RwLockReadGuard<'_, T> {
665        self.data.read()
666    }
667
668    fn try_data(&self) -> Option<RwLockReadGuard<'_, T>> {
669        self.data.try_read()
670    }
671
672    fn cur_state(&self) -> &Arc<AtomicUsize> {
673        &self.cur_state
674    }
675
676    fn read_state(&self) -> &AtomicUsize {
677        &self.read_state
678    }
679}
680
681impl<T: ?Sized> Data<T> for RwData<T> {
682    fn to_ro(&self) -> super::RoData<T> {
683        RoData::from(self)
684    }
685
686    fn has_changed(&self) -> bool {
687        self.has_changed()
688    }
689}
690
691pub struct ReadWriteGuard<'a, T: ?Sized> {
692    guard: RwLockWriteGuard<'a, T>,
693    cur_state: &'a Arc<AtomicUsize>,
694}
695
696impl<T: ?Sized> std::ops::Deref for ReadWriteGuard<'_, T> {
697    type Target = T;
698
699    fn deref(&self) -> &Self::Target {
700        &self.guard
701    }
702}
703
704impl<T: ?Sized> std::ops::DerefMut for ReadWriteGuard<'_, T> {
705    fn deref_mut(&mut self) -> &mut Self::Target {
706        &mut self.guard
707    }
708}
709
710impl<T: ?Sized> Drop for ReadWriteGuard<'_, T> {
711    fn drop(&mut self) {
712        self.cur_state.fetch_add(1, Ordering::Release);
713    }
714}