1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//! Data types that are meant to be shared and read across Duat.
//!
//! The data types revolve around the [`RwLock<T>`] struct from std,
//! and are adapters that may block the mutation of the inner data,
//! for the purpose of making it available for reading to any
//! extension on Duat.
//!
//! The first data type is [`RwData<T>`], which is a read and write
//! wrapper over information. It should mostly not be shared, being
//! used instead to write information while making sure that no other
//! part of the code is still reading it. The second data type is
//! [`RoData<T>`], or read only data. It is derived from the first
//! one, and cannot mutate the inner data.
//!
//! The most common usecase for these data types is in the
//! [`FileWidget], where many readers
//! can peer into the [`Text`] or other useful
//! information, such as the printed lines, cursors, etc.
//!
//! [`FileWidget]: crate::FileWidget<U>
//! [`Text`]: crate::text::Text
pub use self::{
    ro::RoData,
    rw::{ReadWriteGuard, RwData},
    statics::{CurrentFile, CurrentWidget, FileReader},
};

mod ro;
mod rw;
mod statics;

/// Private trait for the [`RwData`] and [`RoData`] structs.
///
/// [`RwData`]: super::RwData
/// [`RoData`]: super::RoData
pub trait Data<T>: private::InnerData<T>
where
    T: ?Sized,
{
    fn to_ro(&self) -> RoData<T>;

    fn has_changed(&self) -> bool;
}

mod private {
    use std::sync::{atomic::AtomicUsize, Arc};

    use parking_lot::RwLockReadGuard;

    pub trait InnerData<T: ?Sized> {
        /// The data, usually an [`Arc`]
        fn data(&self) -> RwLockReadGuard<'_, T>;

        /// Attempt to get the data, that is usually an [`Arc`]
        fn try_data(&self) -> Option<RwLockReadGuard<'_, T>>;

        /// The most up to date state of the data.
        fn cur_state(&self) -> &Arc<AtomicUsize>;

        /// The last read state of the data.
        fn read_state(&self) -> &AtomicUsize;
    }
}