Skip to content

Commit

Permalink
Modularize Tree struct
Browse files Browse the repository at this point in the history
  • Loading branch information
matthunz committed Oct 10, 2023
1 parent fc92b95 commit d4dfa5d
Showing 1 changed file with 115 additions and 83 deletions.
198 changes: 115 additions & 83 deletions src/tree/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use core::fmt;
use dioxus::{
core::{BorrowedAttributeValue, ElementId, Mutation, Mutations},
prelude::TemplateNode,
prelude::{Template, TemplateNode},
};
use slotmap::{DefaultKey, SlotMap};
use std::{any::Any, collections::HashMap, rc::Rc};
Expand Down Expand Up @@ -85,87 +85,22 @@ impl Tree {

pub fn update(&mut self, mutations: Mutations) {
for template in mutations.templates {
fn create_template_element(node: &TemplateNode) -> TreeTemplateNode {
match node {
TemplateNode::Text { text } => {
TreeTemplateNode::Text(Rc::new(text.to_string()))
}
TemplateNode::Element { children, .. } => {
let children = children
.into_iter()
.map(|child| create_template_element(child))
.collect();

TreeTemplateNode::Element { children }
}
_ => todo!(),
}
}

let roots: Vec<_> = template
.roots
.into_iter()
.map(|node| create_template_element(node))
.collect();
self.templates.insert(
template.name.to_owned(),
TreeTemplate {
roots: roots.into_boxed_slice(),
},
);
self.insert_template(template);
}

let mut stack = Vec::new();
for mutation in mutations.edits {
match mutation {
Mutation::LoadTemplate { name, index, id } => {
let template = self.templates.get(name).unwrap();
match &template.roots[index] {
TreeTemplateNode::Text(text) => {
let key = self.nodes.insert(Node {
kind: NodeKind::Text(text.clone()),
});
self.elements.insert(id, key);
}
TreeTemplateNode::Element { children } => {
let mut child_keys = Vec::new();
for elem in children {
match elem {
TreeTemplateNode::Text(text) => {
let key = self.nodes.insert(Node {
kind: NodeKind::Text(text.clone()),
});
child_keys.push(key);
}
_ => todo!(),
}
}

let key = self.nodes.insert(Node {
kind: NodeKind::Element {
attrs: Vec::new(),
children: Vec::new(),
child_keys,
},
});
self.elements.insert(id, key);
}
}

self.load_template(name, index, id);
stack.push(id);
}
Mutation::AppendChildren { id, m } => {
let key = self.elements[&id];
let elem = self.nodes.get_mut(key).unwrap();
if let NodeKind::Element {
ref mut children, ..
} = elem.kind
{
for _ in 0..m {
let child_id = stack.pop().unwrap();
children.push(child_id);
}
}
self.append_children(
key,
std::iter::repeat_with(|| stack.pop().unwrap()).take(m),
);
}
Mutation::SetAttribute {
name,
Expand All @@ -174,22 +109,104 @@ impl Tree {
ns: _,
} => {
let key = self.elements[&id];
let elem = self.nodes.get_mut(key).unwrap();
if let NodeKind::Element { ref mut attrs, .. } = elem.kind {
let _val = match value {
BorrowedAttributeValue::Int(i) => Box::new(i),
_ => todo!(),
};
attrs.push(Attribute {
name: name.to_string(),
value: Box::new(()),
})
}
self.set_attr(key, name.to_string(), value)
}
_ => todo!(),
}
}
}

/// Insert a template into the tree.
pub fn insert_template(&mut self, template: Template) {
let roots: Vec<_> = template
.roots
.into_iter()
.map(|node| create_template_element(node))
.collect();

self.templates.insert(
template.name.to_owned(),
TreeTemplate {
roots: roots.into_boxed_slice(),
},
);
}

/// Append children to an element in the tree.
///
/// ## Panics
/// This function will panic if `key` does not point to an element.
pub fn append_children(
&mut self,
key: DefaultKey,
child_ids: impl IntoIterator<Item = ElementId>,
) {
let node = self.nodes.get_mut(key).unwrap();
if let NodeKind::Element {
ref mut children, ..
} = node.kind
{
children.extend(child_ids)
} else {
panic!("Expected an `Element` node kind.")
}
}

/// Set an attribute of an element in the tree.
///
/// ## Panics
/// This function will panic if `key` does not point to an element.
pub fn set_attr(&mut self, key: DefaultKey, name: String, value: BorrowedAttributeValue) {
let node = self.nodes.get_mut(key).unwrap();
if let NodeKind::Element { ref mut attrs, .. } = node.kind {
let _val = match value {
BorrowedAttributeValue::Int(i) => Box::new(i),
_ => todo!(),
};
attrs.push(Attribute {
name: name,
value: Box::new(()),
})
} else {
panic!("Expected an `Element` node kind.")
}
}

/// Load a template by name into the element `id`.
pub fn load_template(&mut self, name: &str, index: usize, id: ElementId) {
let template = self.templates.get(name).unwrap();
match &template.roots[index] {
TreeTemplateNode::Text(text) => {
let key = self.nodes.insert(Node {
kind: NodeKind::Text(text.clone()),
});
self.elements.insert(id, key);
}
TreeTemplateNode::Element { children } => {
let mut child_keys = Vec::new();
for elem in children {
match elem {
TreeTemplateNode::Text(text) => {
let key = self.nodes.insert(Node {
kind: NodeKind::Text(text.clone()),
});
child_keys.push(key);
}
_ => todo!(),
}
}

let key = self.nodes.insert(Node {
kind: NodeKind::Element {
attrs: Vec::new(),
children: Vec::new(),
child_keys,
},
});
self.elements.insert(id, key);
}
}
}
}

impl fmt::Display for Tree {
Expand Down Expand Up @@ -230,3 +247,18 @@ impl fmt::Display for Tree {
Ok(())
}
}

fn create_template_element(node: &TemplateNode) -> TreeTemplateNode {
match node {
TemplateNode::Text { text } => TreeTemplateNode::Text(Rc::new(text.to_string())),
TemplateNode::Element { children, .. } => {
let children = children
.into_iter()
.map(|child| create_template_element(child))
.collect();

TreeTemplateNode::Element { children }
}
_ => todo!(),
}
}

0 comments on commit d4dfa5d

Please sign in to comment.