Переглянути джерело

chore: update node documentation

nathan 2 роки тому
батько
коміт
3c84e8df51

+ 25 - 1
shared-lib/lib-ot/src/core/document/node.rs

@@ -27,6 +27,7 @@ impl Node {
     }
     }
 }
 }
 
 
+/// Builder for [`Node`]
 pub struct NodeBuilder {
 pub struct NodeBuilder {
     node: Node,
     node: Node,
 }
 }
@@ -38,25 +39,40 @@ impl NodeBuilder {
         }
         }
     }
     }
 
 
+    /// Appends a new node to the end of the builder's node children.
     pub fn add_node(mut self, node: Node) -> Self {
     pub fn add_node(mut self, node: Node) -> Self {
         self.node.children.push(node);
         self.node.children.push(node);
         self
         self
     }
     }
 
 
+    /// Inserts attributes to the builder's node.
+    ///
+    /// The attributes will be replace if they shared the same key
     pub fn insert_attribute(mut self, key: AttributeKey, value: AttributeValue) -> Self {
     pub fn insert_attribute(mut self, key: AttributeKey, value: AttributeValue) -> Self {
         self.node.attributes.insert(key, value);
         self.node.attributes.insert(key, value);
         self
         self
     }
     }
 
 
-    pub fn set_body(mut self, body: NodeBody) -> Self {
+    /// Inserts a body to the builder's node
+    pub fn insert_body(mut self, body: NodeBody) -> Self {
         self.node.body = body;
         self.node.body = body;
         self
         self
     }
     }
+
+    /// Returns the builder's node
     pub fn build(self) -> Node {
     pub fn build(self) -> Node {
         self.node
         self.node
     }
     }
 }
 }
 
 
+/// NodeBody represents as the node's data.
+///
+/// For the moment, the NodeBody can be Empty or Delta. We can extend
+/// the NodeBody by adding a new enum type.
+///
+/// The NodeBody implements the [`OperationTransform`] trait which means it can perform
+/// compose, transform and invert.
+///
 #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
 #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
 pub enum NodeBody {
 pub enum NodeBody {
     Empty,
     Empty,
@@ -79,6 +95,7 @@ impl NodeBody {
 }
 }
 
 
 impl OperationTransform for NodeBody {
 impl OperationTransform for NodeBody {
+    /// Only the same enum variant can perform the compose operation.
     fn compose(&self, other: &Self) -> Result<Self, OTError>
     fn compose(&self, other: &Self) -> Result<Self, OTError>
     where
     where
         Self: Sized,
         Self: Sized,
@@ -93,6 +110,7 @@ impl OperationTransform for NodeBody {
         }
         }
     }
     }
 
 
+    /// Only the same enum variant can perform the transform operation.
     fn transform(&self, other: &Self) -> Result<(Self, Self), OTError>
     fn transform(&self, other: &Self) -> Result<(Self, Self), OTError>
     where
     where
         Self: Sized,
         Self: Sized,
@@ -107,6 +125,7 @@ impl OperationTransform for NodeBody {
         }
         }
     }
     }
 
 
+    /// Only the same enum variant can perform the invert operation.
     fn invert(&self, other: &Self) -> Self {
     fn invert(&self, other: &Self) -> Self {
         match (self, other) {
         match (self, other) {
             (Delta(l), Delta(r)) => Delta(l.invert(r)),
             (Delta(l), Delta(r)) => Delta(l.invert(r)),
@@ -119,6 +138,9 @@ impl OperationTransform for NodeBody {
     }
     }
 }
 }
 
 
+/// Represents the changeset of the [`NodeBody`]
+///
+/// Each NodeBody except the Empty should have its corresponding changeset variant.
 #[derive(Debug, Clone, Serialize, Deserialize)]
 #[derive(Debug, Clone, Serialize, Deserialize)]
 pub enum NodeBodyChangeset {
 pub enum NodeBodyChangeset {
     Delta { delta: TextDelta, inverted: TextDelta },
     Delta { delta: TextDelta, inverted: TextDelta },
@@ -135,6 +157,8 @@ impl NodeBodyChangeset {
     }
     }
 }
 }
 
 
+/// [`NodeData`] represents as a leaf data in the [`NodeTree`].
+///
 #[derive(Clone, Eq, PartialEq, Debug)]
 #[derive(Clone, Eq, PartialEq, Debug)]
 pub struct NodeData {
 pub struct NodeData {
     pub node_type: String,
     pub node_type: String,

+ 29 - 20
shared-lib/lib-ot/src/core/document/node_tree.rs

@@ -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;

+ 16 - 16
shared-lib/lib-ot/src/core/document/operation.rs

@@ -9,29 +9,29 @@ pub enum NodeOperation {
     Insert { path: Path, nodes: Vec<Node> },
     Insert { path: Path, nodes: Vec<Node> },
 
 
     #[serde(rename = "update")]
     #[serde(rename = "update")]
-    Update {
+    UpdateAttributes {
         path: Path,
         path: Path,
         attributes: NodeAttributes,
         attributes: NodeAttributes,
         #[serde(rename = "oldAttributes")]
         #[serde(rename = "oldAttributes")]
         old_attributes: NodeAttributes,
         old_attributes: NodeAttributes,
     },
     },
 
 
-    #[serde(rename = "delete")]
-    Delete { path: Path, nodes: Vec<Node> },
-
     #[serde(rename = "edit-body")]
     #[serde(rename = "edit-body")]
     #[serde(serialize_with = "serialize_edit_body")]
     #[serde(serialize_with = "serialize_edit_body")]
     // #[serde(deserialize_with = "operation_serde::deserialize_edit_body")]
     // #[serde(deserialize_with = "operation_serde::deserialize_edit_body")]
-    EditBody { path: Path, changeset: NodeBodyChangeset },
+    UpdateBody { path: Path, changeset: NodeBodyChangeset },
+
+    #[serde(rename = "delete")]
+    Delete { path: Path, nodes: Vec<Node> },
 }
 }
 
 
 impl NodeOperation {
 impl NodeOperation {
     pub fn path(&self) -> &Path {
     pub fn path(&self) -> &Path {
         match self {
         match self {
             NodeOperation::Insert { path, .. } => path,
             NodeOperation::Insert { path, .. } => path,
-            NodeOperation::Update { path, .. } => path,
+            NodeOperation::UpdateAttributes { path, .. } => path,
             NodeOperation::Delete { path, .. } => path,
             NodeOperation::Delete { path, .. } => path,
-            NodeOperation::EditBody { path, .. } => path,
+            NodeOperation::UpdateBody { path, .. } => path,
         }
         }
     }
     }
     pub fn invert(&self) -> NodeOperation {
     pub fn invert(&self) -> NodeOperation {
@@ -40,11 +40,11 @@ impl NodeOperation {
                 path: path.clone(),
                 path: path.clone(),
                 nodes: nodes.clone(),
                 nodes: nodes.clone(),
             },
             },
-            NodeOperation::Update {
+            NodeOperation::UpdateAttributes {
                 path,
                 path,
                 attributes,
                 attributes,
                 old_attributes,
                 old_attributes,
-            } => NodeOperation::Update {
+            } => NodeOperation::UpdateAttributes {
                 path: path.clone(),
                 path: path.clone(),
                 attributes: old_attributes.clone(),
                 attributes: old_attributes.clone(),
                 old_attributes: attributes.clone(),
                 old_attributes: attributes.clone(),
@@ -53,7 +53,7 @@ impl NodeOperation {
                 path: path.clone(),
                 path: path.clone(),
                 nodes: nodes.clone(),
                 nodes: nodes.clone(),
             },
             },
-            NodeOperation::EditBody { path, changeset: body } => NodeOperation::EditBody {
+            NodeOperation::UpdateBody { path, changeset: body } => NodeOperation::UpdateBody {
                 path: path.clone(),
                 path: path.clone(),
                 changeset: body.inverted(),
                 changeset: body.inverted(),
             },
             },
@@ -65,11 +65,11 @@ impl NodeOperation {
                 path,
                 path,
                 nodes: nodes.clone(),
                 nodes: nodes.clone(),
             },
             },
-            NodeOperation::Update {
+            NodeOperation::UpdateAttributes {
                 attributes,
                 attributes,
                 old_attributes,
                 old_attributes,
                 ..
                 ..
-            } => NodeOperation::Update {
+            } => NodeOperation::UpdateAttributes {
                 path,
                 path,
                 attributes: attributes.clone(),
                 attributes: attributes.clone(),
                 old_attributes: old_attributes.clone(),
                 old_attributes: old_attributes.clone(),
@@ -78,9 +78,9 @@ impl NodeOperation {
                 path,
                 path,
                 nodes: nodes.clone(),
                 nodes: nodes.clone(),
             },
             },
-            NodeOperation::EditBody { path, changeset: body } => NodeOperation::EditBody {
+            NodeOperation::UpdateBody { path, changeset } => NodeOperation::UpdateBody {
                 path: path.clone(),
                 path: path.clone(),
-                changeset: body.clone(),
+                changeset: changeset.clone(),
             },
             },
         }
         }
     }
     }
@@ -127,7 +127,7 @@ mod tests {
 
 
     #[test]
     #[test]
     fn test_serialize_update_operation() {
     fn test_serialize_update_operation() {
-        let insert = NodeOperation::Update {
+        let insert = NodeOperation::UpdateAttributes {
             path: Path(vec![0, 1]),
             path: Path(vec![0, 1]),
             attributes: NodeAttributes::new(),
             attributes: NodeAttributes::new(),
             old_attributes: NodeAttributes::new(),
             old_attributes: NodeAttributes::new(),
@@ -145,7 +145,7 @@ mod tests {
             delta: TextDelta::new(),
             delta: TextDelta::new(),
             inverted: TextDelta::new(),
             inverted: TextDelta::new(),
         };
         };
-        let insert = NodeOperation::EditBody {
+        let insert = NodeOperation::UpdateBody {
             path: Path(vec![0, 1]),
             path: Path(vec![0, 1]),
             changeset,
             changeset,
         };
         };

+ 1 - 1
shared-lib/lib-ot/src/core/document/transaction.rs

@@ -92,7 +92,7 @@ impl<'a> TransactionBuilder<'a> {
             }
             }
         }
         }
 
 
-        self.push(NodeOperation::Update {
+        self.push(NodeOperation::UpdateAttributes {
             path: path.clone(),
             path: path.clone(),
             attributes,
             attributes,
             old_attributes,
             old_attributes,