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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use std::cell::RefCell;
use std::rc::Rc;
pub struct Shared<T: ?Sized> {
rc: Rc<RefCell<T>>,
}
impl<T> Shared<T> {
pub fn new(val: T) -> Self {
Shared {
rc: Rc::new(RefCell::new(val)),
}
}
}
impl<T: ?Sized> Shared<T> {
/// Allows constructing an instance of Shared with a `?Sized T`.
// Note: this leaks implemmentation details, but this is necessary as `CoerceUnsized` is unstable.
pub(crate) fn new_dyn(val: Rc<RefCell<T>>) -> Self {
Shared { rc: val }
}
}
impl<T: ?Sized> Shared<T> {
/// Executes the given function with an immutable reference to the wrapped value.
///
/// # Arguments
///
/// * `func` - The function to execute with a reference to the wrapped value.
///
/// # Panics
///
/// Panics if the wrapped value is being used by an `exec_mut` call.
/// This is only possible if the method was called on a different `Shared` variable corresponding to the same shared value.
///
/// # Example
///
/// ```
/// # use avalanche::shared::Shared;
/// let num = Shared::new(10u8);
/// let squared = num.exec(|&n| n * n);
/// assert_eq!(squared, 100);
/// ```
pub fn exec<Ret, F: FnOnce(&T) -> Ret>(&self, f: F) -> Ret {
f(&self.rc.borrow())
}
/// Executes the given function with a mutable reference to the wrapped value.
///
/// # Arguments
///
/// * `func` - The function to execute with a reference to the wrapped value.
///
/// # Panics
/// Panics if the wrapped value is being used by another `exec` or `exec_mut` call.
/// This is only possible if the method was called on a different `Shared` variable corresponding to the same shared value.
///
/// # Example
///
/// ```
/// # use avalanche::shared::Shared;
/// let sequence = Shared::new([1u8, 2, 3]);
/// sequence.exec_mut(|nums| nums.iter_mut().for_each(|num| *num *= *num));
/// sequence.exec(|nums| assert_eq!(nums, &[1, 4, 9]));
/// ```
pub fn exec_mut<Ret, F: FnOnce(&mut T) -> Ret>(&self, f: F) -> Ret {
f(&mut self.rc.borrow_mut())
}
}
impl<T: ?Sized> Clone for Shared<T> {
fn clone(&self) -> Self {
Shared {
rc: self.rc.clone(),
}
}
}
impl<T: Default> Default for Shared<T> {
fn default() -> Self {
Self::new(Default::default())
}
}
impl<T> From<T> for Shared<T> {
fn from(val: T) -> Self {
Self::new(val)
}
}