rsconnect 0.2.2

Fine-grained reactivity in Rust
Documentation
use std::{
	cell::{Ref, RefCell, RefMut},
	rc::{Rc, Weak},
};

use crate::connect_structs::Connect;

pub type DynNode = Rc<RefCell<dyn Node>>;

pub type DynComputedNode = Rc<RefCell<dyn ComputedNode>>;

pub(crate) type WeakDynComputedNode = Weak<RefCell<dyn ComputedNode>>;

pub(crate) enum AnyDynNode {
	Observed(DynNode),
	Computed(DynComputedNode),
}

impl RefNode for AnyDynNode {
	fn get_derived(&self) -> Ref<Vec<WeakDynComputedNode>> {
		match &self {
			AnyDynNode::Observed(observed) => {
				Ref::map(observed.borrow(), |observed| observed.get_derived())
			}
			AnyDynNode::Computed(computed) => {
				Ref::map(computed.borrow(), |computed| computed.get_derived())
			}
		}
	}

	fn get_mut_derived(&self) -> RefMut<Vec<WeakDynComputedNode>> {
		match self {
			AnyDynNode::Observed(observed) => {
				RefMut::map(observed.borrow_mut(), |observed| observed.get_mut_derived())
			}
			AnyDynNode::Computed(computed) => {
				RefMut::map(computed.borrow_mut(), |computed| computed.get_mut_derived())
			}
		}
	}
}

impl Clone for AnyDynNode {
	fn clone(&self) -> Self {
		match self {
			AnyDynNode::Observed(node) => AnyDynNode::Observed(node.clone()),
			AnyDynNode::Computed(node) => AnyDynNode::Computed(node.clone()),
		}
	}
}

pub enum ConnectNode {
	Observed(DynNode),
	ObservedAny(DynNode),
	Computed(DynComputedNode),
	ComputedAny(DynComputedNode),
	Effected(DynComputedNode),
	EffectedAny(DynComputedNode),
}

impl From<ConnectNode> for AnyDynNode {
	fn from(connect_node: ConnectNode) -> Self {
		match connect_node {
			ConnectNode::Observed(node) | ConnectNode::ObservedAny(node) => {
				AnyDynNode::Observed(node)
			}
			ConnectNode::Computed(node)
			| ConnectNode::ComputedAny(node)
			| ConnectNode::Effected(node)
			| ConnectNode::EffectedAny(node) => AnyDynNode::Computed(node),
		}
	}
}

impl ConnectNode {
	pub(crate) fn as_value_ptr(&self) -> *const () {
		match &self {
			Self::Observed(node) | Self::ObservedAny(node) => node.as_ptr() as *const (),
			Self::Computed(node)
			| Self::ComputedAny(node)
			| Self::Effected(node)
			| Self::EffectedAny(node) => node.as_ptr() as *const (),
		}
	}
}

impl Clone for ConnectNode {
	fn clone(&self) -> Self {
		match self {
			ConnectNode::Observed(node) => ConnectNode::Observed(node.clone()),
			ConnectNode::ObservedAny(node) => ConnectNode::ObservedAny(node.clone()),
			ConnectNode::Computed(node) => ConnectNode::Computed(node.clone()),
			ConnectNode::ComputedAny(node) => ConnectNode::ComputedAny(node.clone()),
			ConnectNode::Effected(node) => ConnectNode::Effected(node.clone()),
			ConnectNode::EffectedAny(node) => ConnectNode::EffectedAny(node.clone()),
		}
	}
}

pub trait ComputedNode: Node {
	fn get_dependencies(&self) -> &Vec<ConnectNode>;

	fn set_dependencies(&mut self, dependencies: Vec<ConnectNode>);

	fn recalculate(&mut self, c: &mut Connect) -> bool;

	fn run_effect(&mut self);
}

pub(crate) trait RefNode {
	fn get_derived(&self) -> Ref<Vec<WeakDynComputedNode>>;

	fn get_mut_derived(&self) -> RefMut<Vec<WeakDynComputedNode>>;
}

pub trait Node {
	fn get_derived(&self) -> &Vec<WeakDynComputedNode>;

	fn get_mut_derived(&mut self) -> &mut Vec<WeakDynComputedNode>;
}

impl RefNode for ConnectNode {
	fn get_derived(&self) -> Ref<Vec<WeakDynComputedNode>> {
		match &self {
			ConnectNode::Observed(observed) | ConnectNode::ObservedAny(observed) => {
				Ref::map(observed.borrow(), |observed| observed.get_derived())
			}
			ConnectNode::Computed(computed)
			| ConnectNode::ComputedAny(computed)
			| ConnectNode::Effected(computed)
			| ConnectNode::EffectedAny(computed) => {
				Ref::map(computed.borrow(), |computed| computed.get_derived())
			}
		}
	}

	fn get_mut_derived(&self) -> RefMut<Vec<WeakDynComputedNode>> {
		match self {
			ConnectNode::Observed(observed) | ConnectNode::ObservedAny(observed) => {
				RefMut::map(observed.borrow_mut(), |observed| observed.get_mut_derived())
			}
			ConnectNode::Computed(computed)
			| ConnectNode::ComputedAny(computed)
			| ConnectNode::Effected(computed)
			| ConnectNode::EffectedAny(computed) => {
				RefMut::map(computed.borrow_mut(), |computed| computed.get_mut_derived())
			}
		}
	}
}

pub trait NodeValueAccess {
	type Value;
	type CompFun;

	fn get_inert(&self) -> Ref<Self::Value>;

	fn set_inert(&self, value: Self::Value) -> Self::Value;

	fn equal(&self, value: &Self::Value) -> bool;
}