use std::sync::Arc;
use crate::option::OptionCell;
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,
}
}
pub fn write(&mut self, val: T) {
self.val = Arc::new(val);
self.inner.replace(self.val.clone());
}
pub fn read(&self) -> &T {
&self.val
}
}
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,
}
}
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)
}
}
}
pub fn read(&mut self) -> &T {
match self.cell.take() {
None => &self.val,
Some(val) => {
self.val = val;
&self.val
}
}
}
}
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));
}
}