1use std::cell::RefCell;
2use std::rc::Rc;
3
4#[derive(Debug)]
6pub struct Signal<T> {
7 inner: Rc<RefCell<T>>,
8}
9
10impl<T> Clone for Signal<T> {
11 fn clone(&self) -> Self {
12 Signal { inner: self.inner.clone() }
13 }
14}
15
16impl<T: Clone> Signal<T> {
17 pub fn get(&self) -> T {
19 self.inner.borrow().clone()
20 }
21}
22
23impl<T> Signal<T> {
24 pub fn with<R>(&self, f: impl FnOnce(&T) -> R) -> R {
27 f(&*self.inner.borrow())
28 }
29}
30
31#[derive(Debug)]
33pub struct SetSignal<T> {
34 inner: Rc<RefCell<T>>,
35}
36
37impl<T> Clone for SetSignal<T> {
38 fn clone(&self) -> Self {
39 SetSignal { inner: self.inner.clone() }
40 }
41}
42
43impl<T> SetSignal<T> {
44 pub fn set(&self, value: T) {
46 *self.inner.borrow_mut() = value;
47 }
48
49 pub fn update(&self, f: impl FnOnce(&mut T)) {
51 f(&mut *self.inner.borrow_mut());
52 }
53}
54
55pub fn create_signal<T>(initial: T) -> (Signal<T>, SetSignal<T>) {
63 let inner = Rc::new(RefCell::new(initial));
64 (
65 Signal { inner: inner.clone() },
66 SetSignal { inner },
67 )
68}
69
70pub trait IntoSignal<T> {
72 fn into_signal(self) -> Signal<T>;
73}
74
75impl<T> IntoSignal<T> for Signal<T> {
76 fn into_signal(self) -> Signal<T> {
77 self
78 }
79}
80
81impl<T> IntoSignal<T> for Rc<RefCell<T>> {
82 fn into_signal(self) -> Signal<T> {
83 Signal { inner: self }
84 }
85}