|
@@ -3,6 +3,7 @@ use crate::core::{Node, NodeAttributes, NodeBodyChangeset, NodeData, NodeOperati
|
|
use crate::errors::{ErrorBuilder, OTError, OTErrorCode};
|
|
use crate::errors::{ErrorBuilder, OTError, OTErrorCode};
|
|
use indextree::{Arena, Children, FollowingSiblings, NodeId};
|
|
use indextree::{Arena, Children, FollowingSiblings, NodeId};
|
|
|
|
|
|
|
|
+///
|
|
pub struct NodeTree {
|
|
pub struct NodeTree {
|
|
arena: Arena<NodeData>,
|
|
arena: Arena<NodeData>,
|
|
root: NodeId,
|
|
root: NodeId,
|
|
@@ -145,12 +146,15 @@ impl NodeTree {
|
|
pub fn apply_op(&mut self, op: &NodeOperation) -> Result<(), OTError> {
|
|
pub fn apply_op(&mut self, op: &NodeOperation) -> Result<(), OTError> {
|
|
match op {
|
|
match op {
|
|
NodeOperation::Insert { path, nodes } => self.insert_nodes(path, nodes),
|
|
NodeOperation::Insert { path, nodes } => self.insert_nodes(path, nodes),
|
|
- NodeOperation::Update { path, attributes, .. } => self.update_node(path, attributes),
|
|
|
|
|
|
+ NodeOperation::UpdateAttributes { path, attributes, .. } => self.update_attributes(path, attributes),
|
|
|
|
+ NodeOperation::UpdateBody { path, changeset } => self.update_body(path, changeset),
|
|
NodeOperation::Delete { path, nodes } => self.delete_node(path, nodes),
|
|
NodeOperation::Delete { path, nodes } => self.delete_node(path, nodes),
|
|
- NodeOperation::EditBody { path, changeset: body } => self.update_body(path, body),
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+ /// Inserts nodes at given path
|
|
|
|
+ ///
|
|
|
|
+ /// returns error if the path is empty
|
|
|
|
+ ///
|
|
fn insert_nodes(&mut self, path: &Path, nodes: &[Node]) -> Result<(), OTError> {
|
|
fn insert_nodes(&mut self, path: &Path, nodes: &[Node]) -> Result<(), OTError> {
|
|
debug_assert!(!path.is_empty());
|
|
debug_assert!(!path.is_empty());
|
|
if path.is_empty() {
|
|
if path.is_empty() {
|
|
@@ -166,6 +170,21 @@ impl NodeTree {
|
|
self.insert_nodes_at_index(parent_node, last_index, nodes)
|
|
self.insert_nodes_at_index(parent_node, last_index, nodes)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /// Inserts nodes before the node with node_id
|
|
|
|
+ ///
|
|
|
|
+ fn insert_nodes_before(&mut self, node_id: &NodeId, nodes: &[Node]) {
|
|
|
|
+ for node in nodes {
|
|
|
|
+ let new_node_id = self.arena.new_node(node.into());
|
|
|
|
+ if node_id.is_removed(&self.arena) {
|
|
|
|
+ tracing::warn!("Node:{:?} is remove before insert", node_id);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ node_id.insert_before(new_node_id, &mut self.arena);
|
|
|
|
+ self.append_nodes(&new_node_id, &node.children);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
fn insert_nodes_at_index(&mut self, parent: NodeId, index: usize, insert_children: &[Node]) -> Result<(), OTError> {
|
|
fn insert_nodes_at_index(&mut self, parent: NodeId, index: usize, insert_children: &[Node]) -> Result<(), OTError> {
|
|
if index == 0 && parent.children(&self.arena).next().is_none() {
|
|
if index == 0 && parent.children(&self.arena).next().is_none() {
|
|
self.append_nodes(&parent, insert_children);
|
|
self.append_nodes(&parent, insert_children);
|
|
@@ -181,30 +200,20 @@ impl NodeTree {
|
|
.child_from_node_at_index(parent, index)
|
|
.child_from_node_at_index(parent, index)
|
|
.ok_or_else(|| ErrorBuilder::new(OTErrorCode::PathNotFound).build())?;
|
|
.ok_or_else(|| ErrorBuilder::new(OTErrorCode::PathNotFound).build())?;
|
|
|
|
|
|
- self.insert_subtree_before(&node_to_insert, insert_children);
|
|
|
|
|
|
+ self.insert_nodes_before(&node_to_insert, insert_children);
|
|
Ok(())
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
|
|
- // recursive append the subtrees to the node
|
|
|
|
- fn append_nodes(&mut self, parent: &NodeId, insert_children: &[Node]) {
|
|
|
|
- for child in insert_children {
|
|
|
|
- let child_id = self.arena.new_node(child.into());
|
|
|
|
- parent.append(child_id, &mut self.arena);
|
|
|
|
-
|
|
|
|
- self.append_nodes(&child_id, &child.children);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- fn insert_subtree_before(&mut self, before: &NodeId, insert_children: &[Node]) {
|
|
|
|
- for child in insert_children {
|
|
|
|
- let child_id = self.arena.new_node(child.into());
|
|
|
|
- before.insert_before(child_id, &mut self.arena);
|
|
|
|
|
|
+ fn append_nodes(&mut self, parent: &NodeId, nodes: &[Node]) {
|
|
|
|
+ for node in nodes {
|
|
|
|
+ let new_node_id = self.arena.new_node(node.into());
|
|
|
|
+ parent.append(new_node_id, &mut self.arena);
|
|
|
|
|
|
- self.append_nodes(&child_id, &child.children);
|
|
|
|
|
|
+ self.append_nodes(&new_node_id, &node.children);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- fn update_node(&mut self, path: &Path, attributes: &NodeAttributes) -> Result<(), OTError> {
|
|
|
|
|
|
+ fn update_attributes(&mut self, path: &Path, attributes: &NodeAttributes) -> Result<(), OTError> {
|
|
self.mut_node_at_path(path, |node_data| {
|
|
self.mut_node_at_path(path, |node_data| {
|
|
let new_attributes = NodeAttributes::compose(&node_data.attributes, attributes)?;
|
|
let new_attributes = NodeAttributes::compose(&node_data.attributes, attributes)?;
|
|
node_data.attributes = new_attributes;
|
|
node_data.attributes = new_attributes;
|