operation.rs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. use crate::core::attributes::Attributes;
  2. use crate::core::document::path::Path;
  3. use crate::core::{NodeBodyChangeset, NodeData};
  4. use crate::errors::OTError;
  5. use serde::{Deserialize, Serialize};
  6. use std::rc::Rc;
  7. #[derive(Debug, Clone, Serialize, Deserialize)]
  8. #[serde(tag = "op")]
  9. pub enum NodeOperation {
  10. #[serde(rename = "insert")]
  11. Insert { path: Path, nodes: Vec<NodeData> },
  12. #[serde(rename = "update-attribute")]
  13. UpdateAttributes {
  14. path: Path,
  15. new: Attributes,
  16. old: Attributes,
  17. },
  18. #[serde(rename = "update-body")]
  19. // #[serde(serialize_with = "serialize_edit_body")]
  20. // #[serde(deserialize_with = "deserialize_edit_body")]
  21. UpdateBody { path: Path, changeset: NodeBodyChangeset },
  22. #[serde(rename = "delete")]
  23. Delete { path: Path, nodes: Vec<NodeData> },
  24. }
  25. impl NodeOperation {
  26. pub fn get_path(&self) -> &Path {
  27. match self {
  28. NodeOperation::Insert { path, .. } => path,
  29. NodeOperation::UpdateAttributes { path, .. } => path,
  30. NodeOperation::Delete { path, .. } => path,
  31. NodeOperation::UpdateBody { path, .. } => path,
  32. }
  33. }
  34. pub fn get_mut_path(&mut self) -> &mut Path {
  35. match self {
  36. NodeOperation::Insert { path, .. } => path,
  37. NodeOperation::UpdateAttributes { path, .. } => path,
  38. NodeOperation::Delete { path, .. } => path,
  39. NodeOperation::UpdateBody { path, .. } => path,
  40. }
  41. }
  42. pub fn invert(&self) -> NodeOperation {
  43. match self {
  44. NodeOperation::Insert { path, nodes } => NodeOperation::Delete {
  45. path: path.clone(),
  46. nodes: nodes.clone(),
  47. },
  48. NodeOperation::UpdateAttributes {
  49. path,
  50. new: attributes,
  51. old: old_attributes,
  52. } => NodeOperation::UpdateAttributes {
  53. path: path.clone(),
  54. new: old_attributes.clone(),
  55. old: attributes.clone(),
  56. },
  57. NodeOperation::Delete { path, nodes } => NodeOperation::Insert {
  58. path: path.clone(),
  59. nodes: nodes.clone(),
  60. },
  61. NodeOperation::UpdateBody { path, changeset: body } => NodeOperation::UpdateBody {
  62. path: path.clone(),
  63. changeset: body.inverted(),
  64. },
  65. }
  66. }
  67. /// Make the `other` operation can be applied to the version after applying the `self` operation.
  68. /// The semantics of transform is used when editing conflicts occur, which is often determined by the version id。
  69. /// For example, if the inserted position has been acquired by others, then it's needed to do the transform to
  70. /// make sure the inserted position is right.
  71. ///
  72. /// # Arguments
  73. ///
  74. /// * `other`: The operation that is going to be transformed
  75. ///
  76. /// # Examples
  77. ///
  78. /// ```
  79. /// use lib_ot::core::{NodeDataBuilder, NodeOperation, Path};
  80. /// let node_1 = NodeDataBuilder::new("text_1").build();
  81. /// let node_2 = NodeDataBuilder::new("text_2").build();
  82. ///
  83. /// let op_1 = NodeOperation::Insert {
  84. /// path: Path(vec![0, 1]),
  85. /// nodes: vec![node_1],
  86. /// };
  87. ///
  88. /// let mut op_2 = NodeOperation::Insert {
  89. /// path: Path(vec![0, 1]),
  90. /// nodes: vec![node_2],
  91. /// };
  92. ///
  93. /// assert_eq!(serde_json::to_string(&op_2).unwrap(), r#"{"op":"insert","path":[0,1],"nodes":[{"type":"text_2"}]}"#);
  94. ///
  95. /// op_1.transform(&mut op_2);
  96. /// assert_eq!(serde_json::to_string(&op_2).unwrap(), r#"{"op":"insert","path":[0,2],"nodes":[{"type":"text_2"}]}"#);
  97. ///
  98. /// ```
  99. pub fn transform(&self, other: &mut NodeOperation) {
  100. match self {
  101. NodeOperation::Insert { path, nodes } => {
  102. let new_path = path.transform(other.get_path(), nodes.len());
  103. *other.get_mut_path() = new_path;
  104. }
  105. NodeOperation::Delete { path, nodes } => {
  106. let new_path = path.transform(other.get_path(), nodes.len());
  107. *other.get_mut_path() = new_path;
  108. }
  109. _ => {
  110. // Only insert/delete will change the path.
  111. }
  112. }
  113. }
  114. }
  115. #[derive(Debug, Clone, Serialize, Deserialize, Default)]
  116. pub struct NodeOperationList {
  117. operations: Vec<Rc<NodeOperation>>,
  118. }
  119. impl NodeOperationList {
  120. pub fn into_inner(self) -> Vec<Rc<NodeOperation>> {
  121. self.operations
  122. }
  123. pub fn add_op(&mut self, operation: NodeOperation) {
  124. self.operations.push(Rc::new(operation));
  125. }
  126. }
  127. impl std::ops::Deref for NodeOperationList {
  128. type Target = Vec<Rc<NodeOperation>>;
  129. fn deref(&self) -> &Self::Target {
  130. &self.operations
  131. }
  132. }
  133. impl std::ops::DerefMut for NodeOperationList {
  134. fn deref_mut(&mut self) -> &mut Self::Target {
  135. &mut self.operations
  136. }
  137. }
  138. impl std::convert::From<Vec<NodeOperation>> for NodeOperationList {
  139. fn from(operations: Vec<NodeOperation>) -> Self {
  140. Self::new(operations)
  141. }
  142. }
  143. impl NodeOperationList {
  144. pub fn new(operations: Vec<NodeOperation>) -> Self {
  145. Self {
  146. operations: operations.into_iter().map(Rc::new).collect(),
  147. }
  148. }
  149. pub fn from_bytes(bytes: Vec<u8>) -> Result<Self, OTError> {
  150. let operation_list = serde_json::from_slice(&bytes).map_err(|err| OTError::serde().context(err))?;
  151. Ok(operation_list)
  152. }
  153. pub fn to_bytes(&self) -> Result<Vec<u8>, OTError> {
  154. let bytes = serde_json::to_vec(self).map_err(|err| OTError::serde().context(err))?;
  155. Ok(bytes)
  156. }
  157. }