rcrefcell/
lib.rs

1use std::{
2  rc::Rc,
3  cell::{
4    RefCell,
5    Ref,
6    RefMut
7  }
8};
9
10pub struct RcCell<A> {
11  value: Rc<RefCell<A>>
12}
13
14impl<A> Clone for RcCell<A> {
15  fn clone(&self) -> RcCell<A> {
16    let value = Rc::clone(&self.value);
17    RcCell {
18      value
19    }
20  }
21}
22
23impl<A> RcCell<A> {
24  pub fn new(value: A) -> RcCell<A> {
25    let value = RefCell::new(value);
26    let value = Rc::new(value);
27    RcCell {
28      value
29    }
30  }
31
32  pub fn borrow(&self) -> Ref<A> {
33    self.value.borrow()
34  }
35
36  pub fn borrow_mut(&self) -> RefMut<A> {
37    self.value.borrow_mut()
38  }
39
40  pub fn update(&self, u: fn(RefMut<A>)) {
41    u(self.borrow_mut())
42  }
43}
44
45#[cfg(test)]
46mod tests {
47  use super::*;
48
49  #[derive(Debug, PartialEq)]
50  struct Data<A> {
51    value: A
52  }
53
54  impl<A> Data<A> {
55    fn new(value: A) -> Data<A> {
56      Data {
57        value,
58      }
59    }
60  }
61
62  #[test]
63  fn multiple_readers() {
64    let data: Data<i32> = Data::new(1);
65    let data = RcCell::new(data);
66  
67    let clone1 = data.clone();
68    let clone2 = data.clone();
69
70    assert_eq!(clone1.borrow().value, 1);
71    assert_eq!(*clone1.borrow(), *clone2.borrow());
72  }
73
74  #[test]
75  fn multiple_writers() {
76    let data: Data<i32> = Data::new(1);
77    let data = RcCell::new(data);
78  
79    let clone1 = data.clone();
80    clone1.update(|mut d| d.value += 1);
81    let clone2 = data.clone();
82    clone2.update(|mut d| d.value *= 3);
83
84    assert_eq!(data.borrow().value, 6);
85    assert_eq!(*clone1.borrow(), *clone2.borrow());
86  }
87
88  #[test]
89  fn example() {
90    #[derive(Debug, PartialEq)]
91    struct Data<A> {
92      value: A
93    }
94  
95    impl<A> Data<A> {
96      fn new(value: A) -> Data<A> {
97        Data {
98          value,
99        }
100      }
101    }
102
103    let data: Data<i32> = Data::new(1);
104
105    let counter: RcCell<Data<i32>> = RcCell::new(data);
106    let counter_a: RcCell<Data<i32>> = counter.clone();
107    let counter_b: RcCell<Data<i32>> = counter.clone();
108
109    counter_a.update(|mut v| v.value += 1);
110    counter_b.borrow_mut().value *= 3;
111
112    assert_eq!(counter.borrow().value, 6);
113    assert_eq!(*counter_a.borrow(), *counter_b.borrow());
114  }
115}