rsconnect 0.2.2

Fine-grained reactivity in Rust
Documentation
use crate::{
	connect_node_update::NodeUpdate,
	connect_structs::Connect,
	node_traits::{AnyDynNode, ConnectNode, DynComputedNode},
	utils::is_value_pointer_equal,
};

fn is_dependency_equal_modified(dependency: &ConnectNode, modified: &AnyDynNode) -> bool {
	match (dependency, modified) {
		(ConnectNode::Observed(dependency), AnyDynNode::Observed(modified))
		| (ConnectNode::ObservedAny(dependency), AnyDynNode::Observed(modified)) => {
			is_value_pointer_equal(dependency.as_ptr(), modified.as_ptr())
		}
		(ConnectNode::Computed(dependency), AnyDynNode::Computed(modified))
		| (ConnectNode::ComputedAny(dependency), AnyDynNode::Computed(modified))
		| (ConnectNode::Effected(dependency), AnyDynNode::Computed(modified))
		| (ConnectNode::EffectedAny(dependency), AnyDynNode::Computed(modified)) => {
			is_value_pointer_equal(dependency.as_ptr(), modified.as_ptr())
		}
		_ => false,
	}
}

pub(crate) trait ConnectDependencies {
	fn remove_computed_from_derived_lists(&self, computed: &DynComputedNode);

	fn add_computed_to_derived_lists(&self, computed: &DynComputedNode);

	fn recalculate_value_and_set_dependencies(
		&mut self,
		computed: &DynComputedNode,
		modified_nodes: &mut Vec<AnyDynNode>,
	);

	fn is_any_dependency_changed(
		&self,
		computed: &DynComputedNode,
		modified_nodes: &[AnyDynNode],
	) -> bool;
}

impl ConnectDependencies for Connect {
	fn remove_computed_from_derived_lists(&self, computed: &DynComputedNode) {
		let computed_clone = computed.clone();
		let computed_borrow = computed_clone.borrow();
		let dependencies = computed_borrow.get_dependencies();
		for dependency in dependencies {
			self.remove_from_derived(computed, dependency);
		}
	}

	fn add_computed_to_derived_lists(&self, computed: &DynComputedNode) {
		let computed_clone = computed.clone();
		let computed_borrow = computed_clone.borrow();
		let dependencies = computed_borrow.get_dependencies();
		for dependency in dependencies {
			self.add_to_derived(computed, dependency);
		}
	}

	fn recalculate_value_and_set_dependencies(
		&mut self,
		computed: &DynComputedNode,
		modified_nodes: &mut Vec<AnyDynNode>,
	) {
		let (is_changed, dependencies) =
			self.get_computed_value(|c| computed.borrow_mut().recalculate(c));
		computed.borrow_mut().run_effect();
		computed.borrow_mut().set_dependencies(dependencies);
		if is_changed {
			modified_nodes.push(AnyDynNode::Computed(computed.clone()));
		}
	}

	fn is_any_dependency_changed(
		&self,
		computed: &DynComputedNode,
		modified_nodes: &[AnyDynNode],
	) -> bool {
		for dependency in computed.borrow().get_dependencies() {
			if modified_nodes.iter().any(|modified_node| {
				is_dependency_equal_modified(dependency, modified_node)
			}) {
				return true;
			}
		}
		false
	}
}