all native-core tests passing

This commit is contained in:
Evan Almloff committed 2023-03-12 15:35:48 -05:00
1 parent ec3e02e4bb
commit 865c5aa957
11 files changed
+350 -324

No files matched your search

+1 -1
View File
@@ -54,7 +54,7 @@ impl DioxusState {
pub fn load_child(&self, rdom: &RealDom, path: &[u8]) -> NodeId {
let mut current = rdom.get(*self.stack.last().unwrap()).unwrap();
for i in path {
let new_id = current.child_ids().unwrap()[*i as usize];
let new_id = current.child_ids()[*i as usize];
current = rdom.get(new_id).unwrap();
}
current.id()
+57 -52
View File
@@ -1,13 +1,14 @@
use anymap::AnyMap;
use parking_lot::RwLock;
use rustc_hash::{FxHashMap, FxHashSet};
use shipyard::{BorrowInfo, Component, IntoBorrow, Unique, UniqueView, View, WorkloadSystem};
use shipyard::{Component, Unique, UniqueView, View, WorkloadSystem};
use std::any::{Any, TypeId};
use std::collections::BTreeMap;
use std::marker::PhantomData;
use std::ops::Deref;
use std::sync::Arc;
use crate::node::FromAnyValue;
use crate::node::{FromAnyValue, NodeType};
use crate::node_ref::{NodeMaskBuilder, NodeView};
use crate::real_dom::{DirtyNodesResult, SendAnyMapWrapper};
use crate::tree::{TreeRef, TreeRefView};
@@ -104,11 +105,11 @@ impl DirtyNodeStates {
}
pub trait State<V: FromAnyValue + Send + Sync = ()>: Any + Send + Sync {
/// This is a tuple of (T: Pass, ..) of states read from the parent required to run this pass
/// This is a tuple of (T: State, ..) of states read from the parent required to run this pass
type ParentDependencies: Dependancy;
/// This is a tuple of (T: Pass, ..) of states read from the children required to run this pass
/// This is a tuple of (T: State, ..) of states read from the children required to run this pass
type ChildDependencies: Dependancy;
/// This is a tuple of (T: Pass, ..) of states read from the node required to run this pass
/// This is a tuple of (T: State, ..) of states read from the node required to run this pass
type NodeDependencies: Dependancy;
/// This is a mask of what aspects of the node are required to run this pass
const NODE_MASK: NodeMaskBuilder<'static>;
@@ -119,7 +120,7 @@ pub trait State<V: FromAnyValue + Send + Sync = ()>: Any + Send + Sync {
node_view: NodeView<V>,
node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
context: &SendAnyMap,
) -> bool;
@@ -128,7 +129,7 @@ pub trait State<V: FromAnyValue + Send + Sync = ()>: Any + Send + Sync {
node_view: NodeView<V>,
node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
context: &SendAnyMap,
) -> Self;
@@ -140,52 +141,22 @@ pub trait State<V: FromAnyValue + Send + Sync = ()>: Any + Send + Sync {
) -> WorkloadSystem;
}
pub struct RunPassView<'a> {
tree: TreeRefView<'a>,
nodes_updated: UniqueView<'a, DirtyNodesResult>,
dirty: UniqueView<'a, DirtyNodeStates>,
ctx: UniqueView<'a, SendAnyMapWrapper>,
}
pub type RunPassView<'a, V = ()> = (
TreeRefView<'a>,
View<'a, NodeType<V>>,
UniqueView<'a, DirtyNodesResult>,
UniqueView<'a, DirtyNodeStates>,
UniqueView<'a, SendAnyMapWrapper>,
);
impl<'v> shipyard::Borrow<'v> for RunPassView<'v> {
type View = RunPassView<'v>;
fn borrow(
world: &'v shipyard::World,
last_run: Option<u32>,
current: u32,
) -> Result<Self::View, shipyard::error::GetStorage> {
Ok(RunPassView {
tree: <TreeRefView<'v> as shipyard::IntoBorrow>::Borrow::borrow(
world, last_run, current,
)?,
nodes_updated:
<UniqueView<'v, DirtyNodesResult> as shipyard::IntoBorrow>::Borrow::borrow(
world, last_run, current,
)?,
dirty: <UniqueView<'v, DirtyNodeStates> as shipyard::IntoBorrow>::Borrow::borrow(
world, last_run, current,
)?,
ctx: <UniqueView<'v, SendAnyMapWrapper> as shipyard::IntoBorrow>::Borrow::borrow(
world, last_run, current,
)?,
})
}
}
pub fn run_pass(
pub fn run_pass<V: FromAnyValue>(
type_id: TypeId,
dependants: FxHashSet<TypeId>,
pass_direction: PassDirection,
view: RunPassView,
view: RunPassView<V>,
mut update_node: impl FnMut(NodeId, &SendAnyMap) -> bool,
) {
let RunPassView {
tree,
nodes_updated,
dirty,
ctx,
} = view;
let (tree, _, nodes_updated, dirty, ctx, ..) = view;
let ctx = ctx.as_ref();
match pass_direction {
PassDirection::ParentToChild => {
@@ -193,7 +164,7 @@ pub fn run_pass(
let id = tree.id_at(id).unwrap();
if (update_node)(id, ctx) {
nodes_updated.insert(id);
for id in tree.children_ids(id).unwrap() {
for id in tree.children_ids(id) {
for dependant in &dependants {
dirty.insert(*dependant, id, height + 1);
}
@@ -283,6 +254,8 @@ pub trait AnyState<V: FromAnyValue + Send + Sync = ()>: State<V> {
}
}
impl<V: FromAnyValue + Send + Sync, S: State<V>> AnyState<V> for S {}
pub struct TypeErasedPass<V: FromAnyValue + Send = ()> {
pub(crate) this_type_id: TypeId,
pub(crate) parent_dependant: bool,
@@ -295,7 +268,17 @@ pub struct TypeErasedPass<V: FromAnyValue + Send = ()> {
phantom: PhantomData<V>,
}
#[derive(Debug)]
impl<V: FromAnyValue + Send> TypeErasedPass<V> {
pub(crate) fn create_workload(&self) -> WorkloadSystem {
(self.workload)(
self.this_type_id,
self.dependants.clone(),
self.pass_direction,
)
}
}
#[derive(Debug, Clone, Copy)]
pub enum PassDirection {
ParentToChild,
ChildToParent,
@@ -319,7 +302,7 @@ impl<'a> AnyMapLike<'a> for &'a SendAnyMap {
}
pub trait Dependancy {
type ElementBorrowed<'a>: IntoBorrow + BorrowInfo;
type ElementBorrowed<'a>;
fn type_ids() -> Box<[TypeId]> {
Box::new([])
@@ -328,8 +311,8 @@ pub trait Dependancy {
macro_rules! impl_dependancy {
($($t:ident),*) => {
impl< $($t: Send + Sync + Component),* > Dependancy for ($($t,)*) {
type ElementBorrowed<'a> = ($(View<'a, $t>,)*);
impl< $($t: Send + Sync + Component + State),* > Dependancy for ($($t,)*) {
type ElementBorrowed<'a> = ($(DependancyView<'a, $t>,)*);
fn type_ids() -> Box<[TypeId]> {
Box::new([$(TypeId::of::<$t>()),*])
@@ -338,6 +321,28 @@ macro_rules! impl_dependancy {
};
}
// TODO: track what components are actually read to update subscriptions
// making this a wrapper makes it possible to implement that optimization without a breaking change
pub struct DependancyView<'a, T> {
inner: &'a T,
}
impl<'a, T> DependancyView<'a, T> {
// This should only be used in the macro. This is not a public API or stable
#[doc(hidden)]
pub fn new(inner: &'a T) -> Self {
Self { inner }
}
}
impl<'a, T> Deref for DependancyView<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.inner
}
}
impl_dependancy!();
impl_dependancy!(A);
impl_dependancy!(A, B);
+57 -62
View File
@@ -101,6 +101,19 @@ pub struct RealDom<V: FromAnyValue + Send + Sync = ()> {
impl<V: FromAnyValue + Send + Sync> RealDom<V> {
pub fn new(mut passes: Box<[TypeErasedPass<V>]>) -> RealDom<V> {
// resolve dependants for each pass
for i in 1..passes.len() {
let (before, after) = passes.split_at_mut(i);
let (current, before) = before.split_last_mut().unwrap();
for pass in before.iter_mut().chain(after.iter_mut()) {
if current
.combined_dependancy_type_ids
.contains(&pass.this_type_id)
{
pass.dependants.insert(current.this_type_id);
}
}
}
let workload = construct_workload(&mut passes);
let (workload, _) = workload.build().unwrap();
let mut world = World::new();
@@ -111,18 +124,9 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
listeners: FxHashSet::default(),
});
let root_id = world.add_entity(root_node);
// resolve dependants for each pass
for i in 1..passes.len() {
let (before, after) = passes.split_at_mut(i);
let (current, before) = before.split_last_mut().unwrap();
for pass in before.iter_mut().chain(after.iter_mut()) {
for dependancy in &current.combined_dependancy_type_ids {
if pass.this_type_id == *dependancy {
pass.dependants.insert(current.this_type_id);
}
}
}
{
let mut tree: TreeMutView = world.borrow().unwrap();
tree.create_node(root_id);
}
let mut passes_updated = FxHashMap::default();
@@ -199,7 +203,7 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
}
pub fn get_mut(&mut self, id: NodeId) -> Option<NodeMut<'_, V>> {
let contains = { self.tree_ref().contains(id) };
let contains = self.tree_ref().contains(id);
contains.then(|| NodeMut::new(id, self))
}
@@ -252,9 +256,8 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
while let Some(id) = stack.pop() {
if let Some(node) = self.get(id) {
f(node);
if let Some(children) = tree.children_ids(id) {
stack.extend(children.iter().copied().rev());
}
let children = tree.children_ids(id);
stack.extend(children.iter().copied().rev());
}
}
}
@@ -266,10 +269,9 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
while let Some(id) = queue.pop_front() {
if let Some(node) = self.get(id) {
f(node);
if let Some(children) = tree.children_ids(id) {
for id in children {
queue.push_back(id);
}
let children = tree.children_ids(id);
for id in children {
queue.push_back(id);
}
}
}
@@ -279,14 +281,13 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
let mut stack = vec![self.root_id()];
while let Some(id) = stack.pop() {
let tree = self.tree_ref();
if let Some(mut children) = tree.children_ids(id) {
drop(tree);
children.reverse();
if let Some(node) = self.get_mut(id) {
let node = node;
f(node);
stack.extend(children.iter());
}
let mut children = tree.children_ids(id);
drop(tree);
children.reverse();
if let Some(node) = self.get_mut(id) {
let node = node;
f(node);
stack.extend(children.iter());
}
}
}
@@ -296,13 +297,12 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
queue.push_back(self.root_id());
while let Some(id) = queue.pop_front() {
let tree = self.tree_ref();
if let Some(children) = tree.children_ids(id) {
drop(tree);
if let Some(node) = self.get_mut(id) {
f(node);
for id in children {
queue.push_back(id);
}
let children = tree.children_ids(id);
drop(tree);
if let Some(node) = self.get_mut(id) {
f(node);
for id in children {
queue.push_back(id);
}
}
}
@@ -375,22 +375,19 @@ pub trait NodeImmutable<V: FromAnyValue + Send + Sync>: Sized {
}
#[inline]
fn child_ids(&self) -> Option<Vec<NodeId>> {
fn child_ids(&self) -> Vec<NodeId> {
self.real_dom().tree_ref().children_ids(self.id())
}
#[inline]
fn children(&self) -> Vec<NodeRef<V>> {
self.child_ids()
.map(|ids| {
ids.iter()
.map(|id| NodeRef {
id: *id,
dom: self.real_dom(),
})
.collect()
.iter()
.map(|id| NodeRef {
id: *id,
dom: self.real_dom(),
})
.unwrap_or_default()
.collect()
}
#[inline]
@@ -409,7 +406,7 @@ pub trait NodeImmutable<V: FromAnyValue + Send + Sync>: Sized {
#[inline]
fn next(&self) -> Option<NodeRef<V>> {
let parent = self.parent_id()?;
let children = self.real_dom().tree_ref().children_ids(parent)?;
let children = self.real_dom().tree_ref().children_ids(parent);
let index = children.iter().position(|id| *id == self.id())?;
if index + 1 < children.len() {
Some(NodeRef {
@@ -424,7 +421,7 @@ pub trait NodeImmutable<V: FromAnyValue + Send + Sync>: Sized {
#[inline]
fn prev(&self) -> Option<NodeRef<V>> {
let parent = self.parent_id()?;
let children = self.real_dom().tree_ref().children_ids(parent)?;
let children = self.real_dom().tree_ref().children_ids(parent);
let index = children.iter().position(|id| *id == self.id())?;
if index > 0 {
Some(NodeRef {
@@ -534,7 +531,7 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
#[inline]
pub fn next_mut(self) -> Option<NodeMut<'a, V>> {
let parent = self.parent_id()?;
let children = self.dom.tree_mut().children_ids(parent)?;
let children = self.dom.tree_mut().children_ids(parent);
let index = children.iter().position(|id| *id == self.id)?;
if index + 1 < children.len() {
Some(NodeMut::new(children[index + 1], self.dom))
@@ -546,7 +543,7 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
#[inline]
pub fn prev_mut(self) -> Option<NodeMut<'a, V>> {
let parent = self.parent_id()?;
let children = self.dom.tree_ref().children_ids(parent)?;
let children = self.dom.tree_ref().children_ids(parent);
let index = children.iter().position(|id| *id == self.id)?;
if index > 0 {
Some(NodeMut::new(children[index - 1], self.dom))
@@ -613,11 +610,10 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
.dirty_nodes
.mark_child_changed(parent_id);
}
if let Some(children_ids) = self.child_ids() {
let children_ids_vec = children_ids.to_vec();
for child in children_ids_vec {
self.dom.get_mut(child).unwrap().remove();
}
let children_ids = self.child_ids();
let children_ids_vec = children_ids.to_vec();
for child in children_ids_vec {
self.dom.get_mut(child).unwrap().remove();
}
self.dom.tree_mut().remove_single(id);
}
@@ -739,13 +735,12 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
let rdom = self.real_dom_mut();
let new_id = rdom.create_node(new_node).id();
if let Some(children) = self.child_ids() {
let children = children.to_vec();
let rdom = self.real_dom_mut();
for child in children {
let child_id = rdom.get_mut(child).unwrap().clone_node();
rdom.get_mut(new_id).unwrap().add_child(child_id);
}
let children = self.child_ids();
let children = children.to_vec();
let rdom = self.real_dom_mut();
for child in children {
let child_id = rdom.get_mut(child).unwrap().clone_node();
rdom.get_mut(new_id).unwrap().add_child(child_id);
}
new_id
}
@@ -894,7 +889,7 @@ fn construct_workload<V: FromAnyValue + Send + Sync>(passes: &mut [TypeErasedPas
.iter_mut()
.enumerate()
.map(|(i, pass)| {
let workload = Some((pass.workload)(pass.dependants.clone()));
let workload = Some(pass.create_workload());
(i, pass, workload)
})
.collect::<Vec<_>>();
@@ -913,7 +908,7 @@ fn construct_workload<V: FromAnyValue + Send + Sync>(passes: &mut [TypeErasedPas
let (_, _, workload) = &mut unresloved_workloads[i];
*workload = workload
.take()
.map(|workload| workload.tag(dependancy_id.to_string()));
.map(|workload| workload.after_all(dependancy_id.to_string()));
}
}
for (_, _, mut workload_system) in unresloved_workloads {
+65 -83
View File
@@ -14,7 +14,7 @@ pub type TreeMutView<'a> = (EntitiesViewMut<'a>, ViewMut<'a, Node>);
pub trait TreeRef {
fn parent_id(&self, id: NodeId) -> Option<NodeId>;
fn children_ids(&self, id: NodeId) -> Option<Vec<NodeId>>;
fn children_ids(&self, id: NodeId) -> Vec<NodeId>;
fn height(&self, id: NodeId) -> Option<u16>;
fn contains(&self, id: NodeId) -> bool;
}
@@ -35,8 +35,10 @@ impl<'a> TreeRef for TreeRefView<'a> {
self.get(id).unwrap().parent
}
fn children_ids(&self, id: NodeId) -> Option<Vec<NodeId>> {
Some(self.get(id).unwrap().children.clone())
fn children_ids(&self, id: NodeId) -> Vec<NodeId> {
self.get(id)
.map(|node| node.children.clone())
.unwrap_or_default()
}
fn height(&self, id: NodeId) -> Option<u16> {
@@ -50,12 +52,10 @@ impl<'a> TreeRef for TreeRefView<'a> {
impl<'a> TreeMut for TreeMutView<'a> {
fn remove(&mut self, id: NodeId) {
fn recurse<'a>(tree: &mut TreeMutView<'a>, id: NodeId) {
fn recurse(tree: &mut TreeMutView<'_>, id: NodeId) {
let children = tree.children_ids(id);
if let Some(children) = children {
for child in children {
recurse(tree, child);
}
for child in children {
recurse(tree, child);
}
}
{
@@ -175,9 +175,12 @@ impl<'a> TreeRef for TreeMutView<'a> {
node_data.get(id).unwrap().parent
}
fn children_ids(&self, id: NodeId) -> Option<Vec<NodeId>> {
fn children_ids(&self, id: NodeId) -> Vec<NodeId> {
let node_data = &self.1;
node_data.get(id).map(|node| node.children.clone()).ok()
node_data
.get(id)
.map(|node| node.children.clone())
.unwrap_or_default()
}
fn height(&self, id: NodeId) -> Option<u16> {
@@ -192,47 +195,51 @@ impl<'a> TreeRef for TreeMutView<'a> {
#[test]
fn creation() {
let mut tree = Tree::new();
let parent_id = tree.root;
tree.insert(parent_id, 1i32);
let mut child = tree.create_node();
child.insert(0i32);
let child_id = child.id();
use shipyard::World;
#[derive(Component)]
struct Num(i32);
let mut world = World::new();
let parent_id = world.add_entity(Num(1i32));
let child_id = world.add_entity(Num(0i32));
let mut tree = world.borrow::<TreeMutView>().unwrap();
tree.create_node(parent_id);
tree.create_node(child_id);
tree.add_child(parent_id, child_id);
println!("Tree: {tree:#?}");
assert_eq!(tree.size(), 2);
assert_eq!(tree.height(parent_id), Some(0));
assert_eq!(tree.height(child_id), Some(1));
assert_eq!(tree.parent_id(parent_id), None);
assert_eq!(tree.parent_id(child_id).unwrap(), parent_id);
assert_eq!(tree.children_ids(parent_id).unwrap(), &[child_id]);
assert_eq!(*tree.get::<i32>(parent_id).unwrap(), 1);
assert_eq!(*tree.get::<i32>(child_id).unwrap(), 0);
assert_eq!(tree.children_ids(parent_id), &[child_id]);
}
#[test]
fn insertion() {
let mut tree = Tree::new();
let parent = tree.root();
tree.insert(parent, 0);
let mut child = tree.create_node();
child.insert(2);
let child = child.id();
use shipyard::World;
#[derive(Component)]
struct Num(i32);
let mut world = World::new();
let parent = world.add_entity(Num(0));
let child = world.add_entity(Num(2));
let before = world.add_entity(Num(1));
let after = world.add_entity(Num(3));
let mut tree = world.borrow::<TreeMutView>().unwrap();
tree.create_node(parent);
tree.create_node(child);
tree.create_node(before);
tree.create_node(after);
tree.add_child(parent, child);
let mut before = tree.create_node();
before.insert(1);
let before = before.id();
tree.insert_before(child, before);
let mut after = tree.create_node();
after.insert(3);
let after = after.id();
tree.insert_after(child, after);
println!("Tree: {tree:#?}");
assert_eq!(tree.size(), 4);
assert_eq!(tree.height(parent), Some(0));
assert_eq!(tree.height(child), Some(1));
assert_eq!(tree.height(before), Some(1));
@@ -240,34 +247,32 @@ fn insertion() {
assert_eq!(tree.parent_id(before).unwrap(), parent);
assert_eq!(tree.parent_id(child).unwrap(), parent);
assert_eq!(tree.parent_id(after).unwrap(), parent);
assert_eq!(tree.children_ids(parent).unwrap(), &[before, child, after]);
assert_eq!(*tree.get::<i32>(parent).unwrap(), 0);
assert_eq!(*tree.get::<i32>(before).unwrap(), 1);
assert_eq!(*tree.get::<i32>(child).unwrap(), 2);
assert_eq!(*tree.get::<i32>(after).unwrap(), 3);
assert_eq!(tree.children_ids(parent), &[before, child, after]);
}
#[test]
fn deletion() {
let mut tree = Tree::new();
let parent = tree.root();
tree.insert(parent, 0);
let mut child = tree.create_node();
child.insert(2);
let child = child.id();
use shipyard::World;
#[derive(Component)]
struct Num(i32);
let mut world = World::new();
let parent = world.add_entity(Num(0));
let child = world.add_entity(Num(2));
let before = world.add_entity(Num(1));
let after = world.add_entity(Num(3));
let mut tree = world.borrow::<TreeMutView>().unwrap();
tree.create_node(parent);
tree.create_node(child);
tree.create_node(before);
tree.create_node(after);
tree.add_child(parent, child);
let mut before = tree.create_node();
before.insert(1);
let before = before.id();
tree.insert_before(child, before);
let mut after = tree.create_node();
after.insert(3);
let after = after.id();
tree.insert_after(child, after);
println!("Tree: {tree:#?}");
assert_eq!(tree.size(), 4);
assert_eq!(tree.height(parent), Some(0));
assert_eq!(tree.height(child), Some(1));
assert_eq!(tree.height(before), Some(1));
@@ -275,49 +280,26 @@ fn deletion() {
assert_eq!(tree.parent_id(before).unwrap(), parent);
assert_eq!(tree.parent_id(child).unwrap(), parent);
assert_eq!(tree.parent_id(after).unwrap(), parent);
assert_eq!(tree.children_ids(parent).unwrap(), &[before, child, after]);
assert_eq!(*tree.get::<i32>(parent).unwrap(), 0);
assert_eq!(*tree.get::<i32>(before).unwrap(), 1);
assert_eq!(*tree.get::<i32>(child).unwrap(), 2);
assert_eq!(*tree.get::<i32>(after).unwrap(), 3);
assert_eq!(tree.children_ids(parent), &[before, child, after]);
tree.remove(child);
println!("Tree: {tree:#?}");
assert_eq!(tree.size(), 3);
assert_eq!(tree.height(parent), Some(0));
assert_eq!(tree.height(before), Some(1));
assert_eq!(tree.height(after), Some(1));
assert_eq!(tree.parent_id(before).unwrap(), parent);
assert_eq!(tree.parent_id(after).unwrap(), parent);
assert_eq!(tree.children_ids(parent).unwrap(), &[before, after]);
assert_eq!(*tree.get::<i32>(parent).unwrap(), 0);
assert_eq!(*tree.get::<i32>(before).unwrap(), 1);
assert_eq!(tree.get::<i32>(child), None);
assert_eq!(*tree.get::<i32>(after).unwrap(), 3);
assert_eq!(tree.children_ids(parent), &[before, after]);
tree.remove(before);
println!("Tree: {tree:#?}");
assert_eq!(tree.size(), 2);
assert_eq!(tree.height(parent), Some(0));
assert_eq!(tree.height(after), Some(1));
assert_eq!(tree.parent_id(after).unwrap(), parent);
assert_eq!(tree.children_ids(parent).unwrap(), &[after]);
assert_eq!(*tree.get::<i32>(parent).unwrap(), 0);
assert_eq!(tree.get::<i32>(before), None);
assert_eq!(*tree.get::<i32>(after).unwrap(), 3);
assert_eq!(tree.children_ids(parent), &[after]);
tree.remove(after);
println!("Tree: {tree:#?}");
assert_eq!(tree.size(), 1);
assert_eq!(tree.height(parent), Some(0));
assert_eq!(tree.children_ids(parent).unwrap(), &[]);
assert_eq!(*tree.get::<i32>(parent).unwrap(), 0);
assert_eq!(tree.get::<i32>(after), None);
assert_eq!(tree.children_ids(parent), &[]);
}
@@ -199,68 +199,68 @@ fn traverse() {
let div_tag = "div".to_string();
assert!(matches!(
&rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
&*rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
NodeType::Element(ElementNode { tag: div_tag, .. })
));
assert!(matches!(
&rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
&*rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
NodeType::Element(ElementNode { tag: div_tag, .. })
));
let text1 = "hello".to_string();
assert!(matches!(
&rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
&*rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
NodeType::Text(text1)
));
let p_tag = "p".to_string();
assert!(matches!(
&rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
&*rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
NodeType::Element(ElementNode { tag: p_tag, .. })
));
let text2 = "world".to_string();
assert!(matches!(
&rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
&*rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
NodeType::Text(text2)
));
let text3 = "hello world".to_string();
assert!(matches!(
&rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
&*rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
NodeType::Text(text3)
));
assert!(matches!(
&rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
&*rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
NodeType::Element(ElementNode { tag: div_tag, .. })
));
assert!(matches!(
&rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
&*rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
NodeType::Text(text3)
));
assert!(matches!(
&rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
&*rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
NodeType::Text(text2)
));
assert!(matches!(
&rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
&*rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
NodeType::Element(ElementNode { tag: p_tag, .. })
));
assert!(matches!(
&rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
&*rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
NodeType::Text(text1)
));
assert!(matches!(
&rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
&*rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
NodeType::Element(ElementNode { tag: div_tag, .. })
));
assert!(matches!(
&rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
&*rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
NodeType::Element(ElementNode { tag: div_tag, .. })
));
assert!(matches!(
&rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
&*rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
NodeType::Element(ElementNode { tag: div_tag, .. })
));
assert!(matches!(
&rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
&*rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
NodeType::Text(text3)
));
}
@@ -335,13 +335,13 @@ fn persist_removes() {
let root_tag = "Root".to_string();
let idx = iter1.next(&rdom).id();
assert!(matches!(
&rdom.get(idx).unwrap().node_type(),
&*rdom.get(idx).unwrap().node_type(),
NodeType::Element(ElementNode { tag: root_tag, .. })
));
let idx = iter2.next(&rdom).id();
assert!(matches!(
&rdom.get(idx).unwrap().node_type(),
&*rdom.get(idx).unwrap().node_type(),
NodeType::Element(ElementNode { tag: root_tag, .. })
));
}
@@ -399,7 +399,7 @@ fn persist_instertions_before() {
let p_tag = "div".to_string();
let idx = iter.next(&rdom).id();
assert!(matches!(
&rdom.get(idx).unwrap().node_type(),
&*rdom.get(idx).unwrap().node_type(),
NodeType::Element(ElementNode { tag: p_tag, .. })
));
}
@@ -456,13 +456,13 @@ fn persist_instertions_after() {
let p_tag = "p".to_string();
let idx = iter.next(&rdom).id();
assert!(matches!(
&rdom.get(idx).unwrap().node_type(),
&*rdom.get(idx).unwrap().node_type(),
NodeType::Element(ElementNode { tag: p_tag, .. })
));
let text = "hello world".to_string();
let idx = iter.next(&rdom).id();
assert!(matches!(
&rdom.get(idx).unwrap().node_type(),
&*rdom.get(idx).unwrap().node_type(),
NodeType::Text(text)
));
}