skima 0.1.0

Rust structural UI library for web
Documentation
use std::cell::RefCell;
use std::marker::PhantomData;
use std::rc::Rc;

use crate::{Backend, Markup};

pub struct Mutable<T> {
	inner: Rc<RefCell<T>>,
}

impl<T: Default> Default for Mutable<T> {
	fn default() -> Self {
		Mutable::new(Default::default())
	}
}

impl<T> Clone for Mutable<T> {
	fn clone(&self) -> Self {
		Mutable {
			inner: self.inner.clone(),
		}
	}
}

impl<T> Mutable<T> {
	pub fn new(value: T) -> Mutable<T> {
		Mutable {
			inner: Rc::new(RefCell::new(value)),
		}
	}

	pub fn set(&self, value: T) {
		*self.inner.borrow_mut() = value
	}

	pub fn replace(&self, value: T) -> T {
		std::mem::replace(&mut self.inner.borrow_mut(), value)
	}

	pub fn setter(&self) -> impl Fn(T) {
		let inner = self.inner.clone();
		move |t| {
			*inner.borrow_mut() = t;
		}
	}

	pub fn current<'a>(&'a self) -> std::cell::Ref<'a, T> {
		self.inner.borrow()
	}
}

impl<T> Mutable<Option<T>> {
	pub fn unwrap<'a>(&'a self) -> std::cell::Ref<'a, T> {
		std::cell::Ref::map(self.inner.borrow(), |r| r.as_ref().unwrap())
	}
}

pub struct Refr<B: Backend, F: Fn(Option<B::Node>)> {
	func: F,
	_b: PhantomData<B>,
}

impl<B: Backend, F: Fn(Option<B::Node>)> Markup<B> for Refr<B, F> {
	fn render(&self, tree: &crate::tree::Tree<B>) {
		let tree = tree.closest_node();
		(self.func)(Some(tree));
	}
	fn diff(&self, _prev: &Self, _tree: &crate::tree::Tree<B>) {}
	fn drop(&self, tree: &crate::tree::Tree<B>, should_unmount: bool) {
		(self.func)(None);
	}
}

pub fn reference<B: Backend>(func: impl Fn(Option<B::Node>)) -> impl Markup<B> {
	Refr {
		func,
		_b: PhantomData,
	}
}