rw-cell 2.0.3

Write data to cell from anything place your application without copy, lock and reading in one place
Documentation
//!Implements the pattern "single producer single consumer"
//! # Example
//!
//!```
//! let (mut w, mut r) = rw_cell::bridge::new("Not good, but ok");
//!
//! assert_eq!(r.read_with_is_new(), (&"Not good, but ok", false));
//!
//! w.write("Not good");
//! assert_eq!(r.read_with_is_new(), (&"Not good", true));
//!
//! w.write("But!!!");
//! assert_eq!(r.read(), &"But!!!");
//! ```

use std::sync::Arc;
use crate::option::OptionCell;

/// Struct for write/read data in/from cell with non-copy and non-lock
pub struct Writer<T> {
    inner: Arc<OptionCell<Arc<T>>>,
    val: Arc<T>
}

impl<T> Writer<T> {
    fn new(cell: Arc<OptionCell<Arc<T>>>) -> Self {
        let val = cell.take().unwrap();
        cell.replace(val.clone());

        Self {
            inner: cell,
            val,
        }
    }

    /// Write value in cell
    ///
    /// # Examples
    ///
    /// ```
    /// let (mut w, mut r) = rw_cell::bridge::new("Not good");
    /// w.write("Good");
    ///
    /// assert_eq!(r.read(), &"Good");
    /// ```
    pub fn write(&mut self, val: T) {
        self.val = Arc::new(val);
        self.inner.replace(self.val.clone());
    }

    /// Return a reference to the value from the cell
    pub fn read(&self) -> &T {
        &self.val
    }
}

/// Struct for read data from cell with non-copy and non-lock
pub struct Reader<T> {
    cell: Arc<OptionCell<Arc<T>>>,
    val: Arc<T>
}

impl<T> Reader<T> {
    fn new(cell: Arc<OptionCell<Arc<T>>>) -> Self {
        Self {
            val: cell.take().unwrap(),
            cell,
        }
    }

    /// Returns a tuple of value references and a boolean value, whether new or not
    ///
    /// # Examples
    ///
    /// ```
    /// let (mut w, mut r) = rw_cell::bridge::new("Not good");
    /// assert_eq!(r.read_with_is_new(), (&"Not good", false));
    ///
    /// w.write("But ok");
    /// assert_eq!(r.read_with_is_new(), (&"But ok", true));
    /// ```
    pub fn read_with_is_new(&mut self) -> (&T, bool) {
        match self.cell.take() {
            None => (&self.val, false),
            Some(val) => {
                self.val = val;
                (&*self.val, true)
            }
        }
    }

    /// Return a reference to the value from the cell
    pub fn read(&mut self) -> &T {
        match self.cell.take() {
            None => &self.val,
            Some(val) => {
                self.val = val;
                &self.val
            }
        }
    }
}

/// Create new cell with [`Writer`] and [`Reader`]
///
/// # Examples
///
/// ```
/// let (mut w, mut r) = rw_cell::bridge::new("Not good");
/// assert_eq!(r.read(), &"Not good");
///
/// w.write("But ok");
/// assert_eq!(r.read_with_is_new(), (&"But ok", true));
/// ```
pub fn new<T>(val: T) -> (Writer<T>, Reader<T>) {
    let cell = Arc::new(OptionCell::new(Arc::new(val)));
    (Writer::new(cell.clone()), Reader::new(cell))
}

pub fn default<T>() -> (Writer<T>, Reader<T>)
where
    T: Default
{
    let cell = Arc::new(OptionCell::new(Arc::new(T::default())));
    (Writer::new(cell.clone()), Reader::new(cell))
}


#[cfg(test)]
mod test {
    use crate::bridge;

    #[test]
    fn test_read() {
        let (mut w, mut r) = bridge::new(vec!["fffff"; 1000]);
        assert_eq!(r.read(), &vec!["fffff"; 1000]);
        w.write(vec!["Not good, but ok"]);
        assert_eq!(r.read(), &vec!["Not good, but ok"]);
    }

    #[test]
    fn test_clone() {
        let (mut tx, mut rx) = bridge::new(vec!["fffff"; 1000]);
        assert_eq!(rx.read(), &vec!["fffff"; 1000]);
        tx.write(vec!["Not good, but ok"]);
        assert_eq!(rx.read(), &vec!["Not good, but ok"]);
    }

    #[test]
    fn test_read_with_is_new() {
        let (mut w, mut r) = bridge::new(vec!["fffff"; 1000]);
        assert_eq!(r.read_with_is_new(), (&vec!["fffff"; 1000], false));
        w.write(vec!["Not good"]);
        assert_eq!(r.read_with_is_new(), (&vec!["Not good"], true));
    }
}