rw_cell/
bridge.rs

1//!Implements the pattern "single producer single consumer"
2//! # Example
3//!
4//!```
5//! let (mut w, mut r) = rw_cell::bridge::new("Not good, but ok");
6//!
7//! assert_eq!(r.read_with_is_new(), (&"Not good, but ok", false));
8//!
9//! w.write("Not good");
10//! assert_eq!(r.read_with_is_new(), (&"Not good", true));
11//!
12//! w.write("But!!!");
13//! assert_eq!(r.read(), &"But!!!");
14//! ```
15
16use std::sync::Arc;
17use crate::option::OptionCell;
18
19/// Struct for write/read data in/from cell with non-copy and non-lock
20pub struct Writer<T> {
21    inner: Arc<OptionCell<Arc<T>>>,
22    val: Arc<T>
23}
24
25impl<T> Writer<T> {
26    fn new(cell: Arc<OptionCell<Arc<T>>>) -> Self {
27        let val = cell.take().unwrap();
28        cell.replace(val.clone());
29
30        Self {
31            inner: cell,
32            val,
33        }
34    }
35
36    /// Write value in cell
37    ///
38    /// # Examples
39    ///
40    /// ```
41    /// let (mut w, mut r) = rw_cell::bridge::new("Not good");
42    /// w.write("Good");
43    ///
44    /// assert_eq!(r.read(), &"Good");
45    /// ```
46    pub fn write(&mut self, val: T) {
47        self.val = Arc::new(val);
48        self.inner.replace(self.val.clone());
49    }
50
51    /// Return a reference to the value from the cell
52    pub fn read(&self) -> &T {
53        &self.val
54    }
55}
56
57/// Struct for read data from cell with non-copy and non-lock
58pub struct Reader<T> {
59    cell: Arc<OptionCell<Arc<T>>>,
60    val: Arc<T>
61}
62
63impl<T> Reader<T> {
64    fn new(cell: Arc<OptionCell<Arc<T>>>) -> Self {
65        Self {
66            val: cell.take().unwrap(),
67            cell,
68        }
69    }
70
71    /// Returns a tuple of value references and a boolean value, whether new or not
72    ///
73    /// # Examples
74    ///
75    /// ```
76    /// let (mut w, mut r) = rw_cell::bridge::new("Not good");
77    /// assert_eq!(r.read_with_is_new(), (&"Not good", false));
78    ///
79    /// w.write("But ok");
80    /// assert_eq!(r.read_with_is_new(), (&"But ok", true));
81    /// ```
82    pub fn read_with_is_new(&mut self) -> (&T, bool) {
83        match self.cell.take() {
84            None => (&self.val, false),
85            Some(val) => {
86                self.val = val;
87                (&*self.val, true)
88            }
89        }
90    }
91
92    /// Return a reference to the value from the cell
93    pub fn read(&mut self) -> &T {
94        match self.cell.take() {
95            None => &self.val,
96            Some(val) => {
97                self.val = val;
98                &self.val
99            }
100        }
101    }
102}
103
104/// Create new cell with [`Writer`] and [`Reader`]
105///
106/// # Examples
107///
108/// ```
109/// let (mut w, mut r) = rw_cell::bridge::new("Not good");
110/// assert_eq!(r.read(), &"Not good");
111///
112/// w.write("But ok");
113/// assert_eq!(r.read_with_is_new(), (&"But ok", true));
114/// ```
115pub fn new<T>(val: T) -> (Writer<T>, Reader<T>) {
116    let cell = Arc::new(OptionCell::new(Arc::new(val)));
117    (Writer::new(cell.clone()), Reader::new(cell))
118}
119
120pub fn default<T>() -> (Writer<T>, Reader<T>)
121where
122    T: Default
123{
124    let cell = Arc::new(OptionCell::new(Arc::new(T::default())));
125    (Writer::new(cell.clone()), Reader::new(cell))
126}
127
128
129#[cfg(test)]
130mod test {
131    use crate::bridge;
132
133    #[test]
134    fn test_read() {
135        let (mut w, mut r) = bridge::new(vec!["fffff"; 1000]);
136        assert_eq!(r.read(), &vec!["fffff"; 1000]);
137        w.write(vec!["Not good, but ok"]);
138        assert_eq!(r.read(), &vec!["Not good, but ok"]);
139    }
140
141    #[test]
142    fn test_clone() {
143        let (mut tx, mut rx) = bridge::new(vec!["fffff"; 1000]);
144        assert_eq!(rx.read(), &vec!["fffff"; 1000]);
145        tx.write(vec!["Not good, but ok"]);
146        assert_eq!(rx.read(), &vec!["Not good, but ok"]);
147    }
148
149    #[test]
150    fn test_read_with_is_new() {
151        let (mut w, mut r) = bridge::new(vec!["fffff"; 1000]);
152        assert_eq!(r.read_with_is_new(), (&vec!["fffff"; 1000], false));
153        w.write(vec!["Not good"]);
154        assert_eq!(r.read_with_is_new(), (&vec!["Not good"], true));
155    }
156}