transaction.rs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. use crate::core::attributes::Attributes;
  2. use crate::core::document::path::Path;
  3. use crate::core::{NodeData, NodeOperation, NodeTree};
  4. use indextree::NodeId;
  5. use super::{NodeBodyChangeset, NodeOperationList};
  6. pub struct Transaction {
  7. operations: NodeOperationList,
  8. }
  9. impl Transaction {
  10. pub fn new(operations: NodeOperationList) -> Transaction {
  11. Transaction { operations }
  12. }
  13. pub fn into_operations(self) -> Vec<NodeOperation> {
  14. self.operations.into_inner()
  15. }
  16. }
  17. impl std::ops::Deref for Transaction {
  18. type Target = NodeOperationList;
  19. fn deref(&self) -> &Self::Target {
  20. &self.operations
  21. }
  22. }
  23. impl std::ops::DerefMut for Transaction {
  24. fn deref_mut(&mut self) -> &mut Self::Target {
  25. &mut self.operations
  26. }
  27. }
  28. pub struct TransactionBuilder<'a> {
  29. node_tree: &'a NodeTree,
  30. operations: NodeOperationList,
  31. }
  32. impl<'a> TransactionBuilder<'a> {
  33. pub fn new(node_tree: &'a NodeTree) -> TransactionBuilder {
  34. TransactionBuilder {
  35. node_tree,
  36. operations: NodeOperationList::default(),
  37. }
  38. }
  39. ///
  40. ///
  41. /// # Arguments
  42. ///
  43. /// * `path`: the path that is used to save the nodes
  44. /// * `nodes`: the nodes you will be save in the path
  45. ///
  46. /// # Examples
  47. ///
  48. /// ```
  49. /// // -- 0 (root)
  50. /// // 0 -- text_1
  51. /// // 1 -- text_2
  52. /// use lib_ot::core::{NodeTree, NodeData, TransactionBuilder};
  53. /// let mut node_tree = NodeTree::new("root");
  54. /// let transaction = TransactionBuilder::new(&node_tree)
  55. /// .insert_nodes_at_path(0,vec![ NodeData::new("text_1"), NodeData::new("text_2")])
  56. /// .finalize();
  57. /// node_tree.apply(transaction).unwrap();
  58. ///
  59. /// node_tree.node_id_at_path(vec![0, 0]);
  60. /// ```
  61. ///
  62. pub fn insert_nodes_at_path<T: Into<Path>>(self, path: T, nodes: Vec<NodeData>) -> Self {
  63. self.push(NodeOperation::Insert {
  64. path: path.into(),
  65. nodes,
  66. })
  67. }
  68. ///
  69. ///
  70. /// # Arguments
  71. ///
  72. /// * `path`: the path that is used to save the nodes
  73. /// * `node`: the node data will be saved in the path
  74. ///
  75. /// # Examples
  76. ///
  77. /// ```
  78. /// // 0
  79. /// // -- 0
  80. /// // |-- text
  81. /// use lib_ot::core::{NodeTree, NodeData, TransactionBuilder};
  82. /// let mut node_tree = NodeTree::new("root");
  83. /// let transaction = TransactionBuilder::new(&node_tree)
  84. /// .insert_node_at_path(0, NodeData::new("text"))
  85. /// .finalize();
  86. /// node_tree.apply(transaction).unwrap();
  87. /// ```
  88. ///
  89. pub fn insert_node_at_path<T: Into<Path>>(self, path: T, node: NodeData) -> Self {
  90. self.insert_nodes_at_path(path, vec![node])
  91. }
  92. pub fn update_attributes_at_path(mut self, path: &Path, attributes: Attributes) -> Self {
  93. match self.node_tree.get_node_at_path(path) {
  94. Some(node) => {
  95. let mut old_attributes = Attributes::new();
  96. for key in attributes.keys() {
  97. let old_attrs = &node.attributes;
  98. if let Some(value) = old_attrs.get(key.as_str()) {
  99. old_attributes.insert(key.clone(), value.clone());
  100. }
  101. }
  102. self.operations.push(NodeOperation::UpdateAttributes {
  103. path: path.clone(),
  104. attributes,
  105. old_attributes,
  106. });
  107. }
  108. None => tracing::warn!("Update attributes at path: {:?} failed. Node is not exist", path),
  109. }
  110. self
  111. }
  112. pub fn update_body_at_path(mut self, path: &Path, changeset: NodeBodyChangeset) -> Self {
  113. match self.node_tree.node_id_at_path(path) {
  114. Some(_) => {
  115. self.operations.push(NodeOperation::UpdateBody {
  116. path: path.clone(),
  117. changeset,
  118. });
  119. }
  120. None => tracing::warn!("Update attributes at path: {:?} failed. Node is not exist", path),
  121. }
  122. self
  123. }
  124. pub fn delete_node_at_path(self, path: &Path) -> Self {
  125. self.delete_nodes_at_path(path, 1)
  126. }
  127. pub fn delete_nodes_at_path(mut self, path: &Path, length: usize) -> Self {
  128. let mut node = self.node_tree.node_id_at_path(path).unwrap();
  129. let mut deleted_nodes = vec![];
  130. for _ in 0..length {
  131. deleted_nodes.push(self.get_deleted_nodes(node));
  132. node = self.node_tree.following_siblings(node).next().unwrap();
  133. }
  134. self.operations.push(NodeOperation::Delete {
  135. path: path.clone(),
  136. nodes: deleted_nodes,
  137. });
  138. self
  139. }
  140. fn get_deleted_nodes(&self, node_id: NodeId) -> NodeData {
  141. let node_data = self.node_tree.get_node(node_id).unwrap();
  142. let mut children = vec![];
  143. self.node_tree.children_from_node(node_id).for_each(|child_id| {
  144. children.push(self.get_deleted_nodes(child_id));
  145. });
  146. NodeData {
  147. node_type: node_data.node_type.clone(),
  148. attributes: node_data.attributes.clone(),
  149. body: node_data.body.clone(),
  150. children,
  151. }
  152. }
  153. pub fn push(mut self, op: NodeOperation) -> Self {
  154. self.operations.push(op);
  155. self
  156. }
  157. pub fn finalize(self) -> Transaction {
  158. Transaction::new(self.operations)
  159. }
  160. }