use std::cell::RefCell;
use std::rc::Rc;
#[derive(Debug)]
pub struct Signal<T> {
inner: Rc<RefCell<T>>,
}
impl<T> Clone for Signal<T> {
fn clone(&self) -> Self {
Signal { inner: self.inner.clone() }
}
}
impl<T: Clone> Signal<T> {
pub fn get(&self) -> T {
self.inner.borrow().clone()
}
}
impl<T> Signal<T> {
pub fn with<R>(&self, f: impl FnOnce(&T) -> R) -> R {
f(&*self.inner.borrow())
}
}
#[derive(Debug)]
pub struct SetSignal<T> {
inner: Rc<RefCell<T>>,
}
impl<T> Clone for SetSignal<T> {
fn clone(&self) -> Self {
SetSignal { inner: self.inner.clone() }
}
}
impl<T> SetSignal<T> {
pub fn set(&self, value: T) {
*self.inner.borrow_mut() = value;
}
pub fn update(&self, f: impl FnOnce(&mut T)) {
f(&mut *self.inner.borrow_mut());
}
}
pub fn create_signal<T>(initial: T) -> (Signal<T>, SetSignal<T>) {
let inner = Rc::new(RefCell::new(initial));
(
Signal { inner: inner.clone() },
SetSignal { inner },
)
}
pub trait IntoSignal<T> {
fn into_signal(self) -> Signal<T>;
}
impl<T> IntoSignal<T> for Signal<T> {
fn into_signal(self) -> Signal<T> {
self
}
}
impl<T> IntoSignal<T> for Rc<RefCell<T>> {
fn into_signal(self) -> Signal<T> {
Signal { inner: self }
}
}