use crate::core::attributes::Attributes; use crate::core::{Node, NodeBodyChangeset, NodeData, NodeOperation, OperationTransform, Path, Transaction}; use crate::errors::{ErrorBuilder, OTError, OTErrorCode}; use indextree::{Arena, Children, FollowingSiblings, NodeId}; use std::rc::Rc; use super::NodeOperationList; /// pub struct NodeTree { arena: Arena, root: NodeId, } impl Default for NodeTree { fn default() -> Self { Self::new("root") } } impl NodeTree { pub fn new(root_name: &str) -> NodeTree { let mut arena = Arena::new(); let root = arena.new_node(Node::new(root_name)); NodeTree { arena, root } } pub fn from_bytes(root_name: &str, bytes: Vec) -> Result { let operations = NodeOperationList::from_bytes(bytes)?; Self::from_operations(root_name, operations) } pub fn from_operations(root_name: &str, operations: NodeOperationList) -> Result { let mut node_tree = NodeTree::new(root_name); for operation in operations.into_inner().into_iter() { let _ = node_tree.apply_op(operation)?; } Ok(node_tree) } pub fn get_node(&self, node_id: NodeId) -> Option<&Node> { Some(self.arena.get(node_id)?.get()) } pub fn get_node_at_path(&self, path: &Path) -> Option<&Node> { { let node_id = self.node_id_at_path(path)?; self.get_node(node_id) } } /// /// # Examples /// /// ``` /// use std::rc::Rc; /// use lib_ot::core::{NodeOperation, NodeTree, NodeData, Path}; /// let nodes = vec![NodeData::new("text".to_string())]; /// let root_path: Path = vec![0].into(); /// let op = NodeOperation::Insert {path: root_path.clone(),nodes }; /// /// let mut node_tree = NodeTree::new("root"); /// node_tree.apply_op(Rc::new(op)).unwrap(); /// let node_id = node_tree.node_id_at_path(&root_path).unwrap(); /// let node_path = node_tree.path_from_node_id(node_id); /// debug_assert_eq!(node_path, root_path); /// ``` pub fn node_id_at_path>(&self, path: T) -> Option { let path = path.into(); if path.is_empty() { return Some(self.root); } let mut iterate_node = self.root; for id in path.iter() { iterate_node = self.child_from_node_at_index(iterate_node, *id)?; } Some(iterate_node) } pub fn path_from_node_id(&self, node_id: NodeId) -> Path { let mut path = vec![]; let mut current_node = node_id; // Use .skip(1) on the ancestors iterator to skip the root node. let ancestors = node_id.ancestors(&self.arena).skip(1); for parent_node in ancestors { let counter = self.index_of_node(parent_node, current_node); path.push(counter); current_node = parent_node; } Path(path) } fn index_of_node(&self, parent_node: NodeId, child_node: NodeId) -> usize { let mut counter: usize = 0; let iter = parent_node.children(&self.arena); for node in iter { if node == child_node { return counter; } counter += 1; } counter } /// Returns the note_id at the position of the tree with id note_id /// # Arguments /// /// * `node_id`: the node id of the child's parent /// * `index`: index of the node in parent children list /// /// returns: Option /// /// # Examples /// /// ``` /// use std::rc::Rc; /// use lib_ot::core::{NodeOperation, NodeTree, NodeData, Path}; /// let node_1 = NodeData::new("text".to_string()); /// let inserted_path: Path = vec![0].into(); /// /// let mut node_tree = NodeTree::new("root"); /// let op = NodeOperation::Insert {path: inserted_path.clone(),nodes: vec![node_1.clone()] }; /// node_tree.apply_op(Rc::new(op)).unwrap(); /// /// let node_2 = node_tree.get_node_at_path(&inserted_path).unwrap(); /// assert_eq!(node_2.node_type, node_1.node_type); /// ``` pub fn child_from_node_at_index(&self, node_id: NodeId, index: usize) -> Option { let children = node_id.children(&self.arena); for (counter, child) in children.enumerate() { if counter == index { return Some(child); } } None } /// Returns all children whose parent node id is node_id /// /// * `node_id`: the children's parent node id /// pub fn children_from_node(&self, node_id: NodeId) -> Children<'_, Node> { node_id.children(&self.arena) } /// /// # Arguments /// /// * `node_id`: if the node_is is None, then will use root node_id. /// /// returns number of the children of the root node /// pub fn number_of_children(&self, node_id: Option) -> usize { match node_id { None => self.root.children(&self.arena).count(), Some(node_id) => node_id.children(&self.arena).count(), } } pub fn following_siblings(&self, node_id: NodeId) -> FollowingSiblings<'_, Node> { node_id.following_siblings(&self.arena) } pub fn apply_transaction(&mut self, transaction: Transaction) -> Result<(), OTError> { let operations = transaction.into_operations(); for operation in operations { self.apply_op(operation)?; } Ok(()) } pub fn apply_op(&mut self, op: Rc) -> Result<(), OTError> { let op = match Rc::try_unwrap(op) { Ok(op) => op, Err(op) => op.as_ref().clone(), }; match op { NodeOperation::Insert { path, nodes } => self.insert_nodes(&path, nodes), NodeOperation::UpdateAttributes { path, new, .. } => self.update_attributes(&path, new), NodeOperation::UpdateBody { path, changeset } => self.update_body(&path, changeset), NodeOperation::Delete { path, nodes } => self.delete_node(&path, nodes), } } /// Inserts nodes at given path /// /// returns error if the path is empty /// fn insert_nodes(&mut self, path: &Path, nodes: Vec) -> Result<(), OTError> { debug_assert!(!path.is_empty()); if path.is_empty() { return Err(OTErrorCode::PathIsEmpty.into()); } let (parent_path, last_path) = path.split_at(path.0.len() - 1); let last_index = *last_path.first().unwrap(); let parent_node = self .node_id_at_path(parent_path) .ok_or_else(|| ErrorBuilder::new(OTErrorCode::PathNotFound).build())?; 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: Vec) { for node in nodes { let (node, children) = node.split(); let new_node_id = self.arena.new_node(node); 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, children); } } fn insert_nodes_at_index(&mut self, parent: NodeId, index: usize, nodes: Vec) -> Result<(), OTError> { if index == 0 && parent.children(&self.arena).next().is_none() { self.append_nodes(&parent, nodes); return Ok(()); } // Append the node to the end of the children list if index greater or equal to the // length of the children. if index >= parent.children(&self.arena).count() { self.append_nodes(&parent, nodes); return Ok(()); } let node_to_insert = self .child_from_node_at_index(parent, index) .ok_or_else(|| ErrorBuilder::new(OTErrorCode::PathNotFound).build())?; self.insert_nodes_before(&node_to_insert, nodes); Ok(()) } fn append_nodes(&mut self, parent: &NodeId, nodes: Vec) { for node in nodes { let (node, children) = node.split(); let new_node_id = self.arena.new_node(node); parent.append(new_node_id, &mut self.arena); self.append_nodes(&new_node_id, children); } } fn update_attributes(&mut self, path: &Path, attributes: Attributes) -> Result<(), OTError> { self.mut_node_at_path(path, |node| { let new_attributes = Attributes::compose(&node.attributes, &attributes)?; node.attributes = new_attributes; Ok(()) }) } fn delete_node(&mut self, path: &Path, nodes: Vec) -> Result<(), OTError> { let mut update_node = self .node_id_at_path(path) .ok_or_else(|| ErrorBuilder::new(OTErrorCode::PathNotFound).build())?; for _ in 0..nodes.len() { let next = update_node.following_siblings(&self.arena).next(); update_node.remove_subtree(&mut self.arena); if let Some(next_id) = next { update_node = next_id; } else { break; } } Ok(()) } fn update_body(&mut self, path: &Path, changeset: NodeBodyChangeset) -> Result<(), OTError> { self.mut_node_at_path(path, |node| { node.apply_body_changeset(changeset); Ok(()) }) } fn mut_node_at_path(&mut self, path: &Path, f: F) -> Result<(), OTError> where F: FnOnce(&mut Node) -> Result<(), OTError>, { let node_id = self .node_id_at_path(path) .ok_or_else(|| ErrorBuilder::new(OTErrorCode::PathNotFound).build())?; match self.arena.get_mut(node_id) { None => tracing::warn!("The path: {:?} does not contain any nodes", path), Some(node) => { let node = node.get_mut(); let _ = f(node)?; } } Ok(()) } }