Skip to main content

cranpose_core/
owned.rs

1use std::{
2    cell::{Ref, RefCell, RefMut},
3    rc::Rc,
4};
5
6/// Single-threaded owner for values remembered by the Composer.
7///
8/// This type stores `T` inside an `Rc<RefCell<...>>`, allowing cheap cloning of the
9/// handle while keeping ownership of `T` within the composition.
10pub struct Owned<T> {
11    inner: Rc<RefCell<T>>,
12}
13
14impl<T> Clone for Owned<T> {
15    fn clone(&self) -> Self {
16        Self {
17            inner: Rc::clone(&self.inner),
18        }
19    }
20}
21
22impl<T> Owned<T> {
23    pub fn new(value: T) -> Self {
24        Self {
25            inner: Rc::new(RefCell::new(value)),
26        }
27    }
28
29    /// Run `f` with an immutable reference to the stored value.
30    pub fn with<R>(&self, f: impl FnOnce(&T) -> R) -> R {
31        let borrow = self.inner.borrow();
32        f(&*borrow)
33    }
34
35    /// Run `f` with a mutable reference to the stored value.
36    pub fn update<R>(&self, f: impl FnOnce(&mut T) -> R) -> R {
37        let mut borrow = self.inner.borrow_mut();
38        f(&mut *borrow)
39    }
40
41    /// Borrow the stored value immutably.
42    pub fn borrow(&self) -> Ref<'_, T> {
43        self.inner.borrow()
44    }
45
46    /// Borrow the stored value mutably.
47    pub fn borrow_mut(&self) -> RefMut<'_, T> {
48        self.inner.borrow_mut()
49    }
50
51    /// Replace the stored value entirely.
52    pub fn replace(&self, new_value: T) {
53        *self.inner.borrow_mut() = new_value;
54    }
55}