Skip to content

Commit bb8e048

Browse files
committed
feat: serialize
1 parent ef65551 commit bb8e048

File tree

4 files changed

+119
-33
lines changed

4 files changed

+119
-33
lines changed

shared-lib/lib-ot/src/core/document/document.rs

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use crate::core::document::position::Position;
2-
use crate::core::{DocumentOperation, NodeAttributes, NodeData, OperationTransform, TextDelta, Transaction};
2+
use crate::core::{
3+
DocumentOperation, NodeAttributes, NodeData, NodeSubTree, OperationTransform, TextDelta, Transaction,
4+
};
35
use crate::errors::{ErrorBuilder, OTError, OTErrorCode};
46
use indextree::{Arena, NodeId};
57

@@ -100,51 +102,59 @@ impl DocumentTree {
100102
}
101103
}
102104

103-
fn apply_insert(&mut self, path: &Position, nodes: &Vec<NodeData>) -> Result<(), OTError> {
105+
fn apply_insert(&mut self, path: &Position, nodes: &Vec<NodeSubTree>) -> Result<(), OTError> {
104106
let parent_path = &path.0[0..(path.0.len() - 1)];
105107
let last_index = path.0[path.0.len() - 1];
106108
let parent_node = self
107109
.node_at_path(&Position(parent_path.to_vec()))
108110
.ok_or(ErrorBuilder::new(OTErrorCode::PathNotFound).build())?;
109-
let mut inserted_nodes = Vec::new();
111+
// let mut inserted_nodes = Vec::new();
112+
//
113+
// for node in nodes {
114+
// inserted_nodes.push(self.arena.new_node(node.to_node_data()));
115+
// }
110116

111-
for node in nodes {
112-
inserted_nodes.push(self.arena.new_node(node.clone()));
113-
}
114-
115-
self.insert_child_at_index(parent_node, last_index, &inserted_nodes)
117+
self.insert_child_at_index(parent_node, last_index, nodes.as_ref())
116118
}
117119

118120
fn insert_child_at_index(
119121
&mut self,
120122
parent: NodeId,
121123
index: usize,
122-
insert_children: &[NodeId],
124+
insert_children: &[NodeSubTree],
123125
) -> Result<(), OTError> {
124126
if index == 0 && parent.children(&self.arena).next().is_none() {
125-
for id in insert_children {
126-
parent.append(*id, &mut self.arena);
127-
}
127+
self.append_subtree(&parent, insert_children);
128128
return Ok(());
129129
}
130130

131131
let children_length = parent.children(&self.arena).fold(0, |counter, _| counter + 1);
132132

133133
if index == children_length {
134-
for id in insert_children {
135-
parent.append(*id, &mut self.arena);
136-
}
134+
self.append_subtree(&parent, insert_children);
137135
return Ok(());
138136
}
139137

140138
let node_to_insert = self
141139
.child_at_index_of_path(parent, index)
142140
.ok_or(ErrorBuilder::new(OTErrorCode::PathNotFound).build())?;
143141

142+
self.insert_subtree_before(&node_to_insert, insert_children);
143+
Ok(())
144+
}
145+
146+
fn append_subtree(&mut self, parent: &NodeId, insert_children: &[NodeSubTree]) {
147+
for child in insert_children {
148+
let child_id = self.arena.new_node(child.to_node_data());
149+
parent.append(child_id, &mut self.arena);
150+
}
151+
}
152+
153+
fn insert_subtree_before(&mut self, before: &NodeId, insert_children: &[NodeSubTree]) {
144154
for id in insert_children {
145-
node_to_insert.insert_before(*id, &mut self.arena);
155+
let child_id = self.arena.new_node(id.to_node_data());
156+
before.insert_before(child_id, &mut self.arena);
146157
}
147-
Ok(())
148158
}
149159

150160
fn apply_update(&mut self, path: &Position, attributes: &NodeAttributes) -> Result<(), OTError> {

shared-lib/lib-ot/src/core/document/document_operation.rs

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
use crate::core::document::position::Position;
2-
use crate::core::{NodeAttributes, NodeData, TextDelta};
2+
use crate::core::{NodeAttributes, NodeSubTree, TextDelta};
33

44
#[derive(Clone, serde::Serialize, serde::Deserialize)]
5+
#[serde(tag = "type")]
56
pub enum DocumentOperation {
6-
Insert {
7-
path: Position,
8-
nodes: Vec<NodeData>,
9-
},
7+
#[serde(rename = "insert-operation")]
8+
Insert { path: Position, nodes: Vec<NodeSubTree> },
9+
#[serde(rename = "update-operation")]
1010
Update {
1111
path: Position,
1212
attributes: NodeAttributes,
13+
#[serde(rename = "oldAttributes")]
1314
old_attributes: NodeAttributes,
1415
},
15-
Delete {
16-
path: Position,
17-
nodes: Vec<NodeData>,
18-
},
16+
#[serde(rename = "delete-operation")]
17+
Delete { path: Position, nodes: Vec<NodeSubTree> },
18+
#[serde(rename = "text-edit-operation")]
1919
TextEdit {
2020
path: Position,
2121
delta: TextDelta,
@@ -101,7 +101,7 @@ impl DocumentOperation {
101101

102102
#[cfg(test)]
103103
mod tests {
104-
use crate::core::Position;
104+
use crate::core::{Delta, DocumentOperation, NodeAttributes, NodeSubTree, Position};
105105

106106
#[test]
107107
fn test_transform_path_1() {
@@ -150,4 +150,45 @@ mod tests {
150150
vec![0, 6]
151151
);
152152
}
153+
154+
#[test]
155+
fn test_serialize_insert_operation() {
156+
let insert = DocumentOperation::Insert {
157+
path: Position(vec![0, 1]),
158+
nodes: vec![NodeSubTree::new("text")],
159+
};
160+
let result = serde_json::to_string(&insert).unwrap();
161+
assert_eq!(
162+
result,
163+
r#"{"type":"insert-operation","path":[0,1],"nodes":[{"node_type":"text","attributes":{}}]}"#
164+
);
165+
}
166+
167+
#[test]
168+
fn test_serialize_update_operation() {
169+
let insert = DocumentOperation::Update {
170+
path: Position(vec![0, 1]),
171+
attributes: NodeAttributes::new(),
172+
old_attributes: NodeAttributes::new(),
173+
};
174+
let result = serde_json::to_string(&insert).unwrap();
175+
assert_eq!(
176+
result,
177+
r#"{"type":"update-operation","path":[0,1],"attributes":{},"oldAttributes":{}}"#
178+
);
179+
}
180+
181+
#[test]
182+
fn test_serialize_text_edit_operation() {
183+
let insert = DocumentOperation::TextEdit {
184+
path: Position(vec![0, 1]),
185+
delta: Delta::new(),
186+
inverted: Delta::new(),
187+
};
188+
let result = serde_json::to_string(&insert).unwrap();
189+
assert_eq!(
190+
result,
191+
r#"{"type":"text-edit-operation","path":[0,1],"delta":[],"inverted":[]}"#
192+
);
193+
}
153194
}

shared-lib/lib-ot/src/core/document/node.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::core::{NodeAttributes, TextDelta};
22

3-
#[derive(Clone, serde::Serialize, serde::Deserialize)]
3+
#[derive(Clone)]
44
pub struct NodeData {
55
pub node_type: String,
66
pub attributes: NodeAttributes,
@@ -16,3 +16,32 @@ impl NodeData {
1616
}
1717
}
1818
}
19+
20+
#[derive(Clone, serde::Serialize, serde::Deserialize)]
21+
pub struct NodeSubTree {
22+
pub node_type: String,
23+
pub attributes: NodeAttributes,
24+
#[serde(skip_serializing_if = "Option::is_none")]
25+
pub delta: Option<TextDelta>,
26+
#[serde(skip_serializing_if = "Vec::is_empty")]
27+
pub children: Vec<Box<NodeSubTree>>,
28+
}
29+
30+
impl NodeSubTree {
31+
pub fn new(node_type: &str) -> NodeSubTree {
32+
NodeSubTree {
33+
node_type: node_type.into(),
34+
attributes: NodeAttributes::new(),
35+
delta: None,
36+
children: Vec::new(),
37+
}
38+
}
39+
40+
pub fn to_node_data(&self) -> NodeData {
41+
NodeData {
42+
node_type: self.node_type.clone(),
43+
attributes: self.attributes.clone(),
44+
delta: self.delta.clone(),
45+
}
46+
}
47+
}

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::core::document::position::Position;
2-
use crate::core::{DocumentOperation, DocumentTree, NodeAttributes, NodeData};
2+
use crate::core::{DocumentOperation, DocumentTree, NodeAttributes, NodeSubTree};
33
use std::collections::HashMap;
44

55
pub struct Transaction {
@@ -25,7 +25,7 @@ impl<'a> TransactionBuilder<'a> {
2525
}
2626
}
2727

28-
pub fn insert_nodes_at_path(&mut self, path: &Position, nodes: &[NodeData]) {
28+
pub fn insert_nodes_at_path(&mut self, path: &Position, nodes: &[NodeSubTree]) {
2929
self.push(DocumentOperation::Insert {
3030
path: path.clone(),
3131
nodes: nodes.to_vec(),
@@ -59,11 +59,17 @@ impl<'a> TransactionBuilder<'a> {
5959

6060
pub fn delete_nodes_at_path(&mut self, path: &Position, length: usize) {
6161
let mut node = self.document.node_at_path(path).unwrap();
62-
let mut deleted_nodes: Vec<NodeData> = Vec::new();
62+
let mut deleted_nodes: Vec<NodeSubTree> = Vec::new();
6363

6464
for _ in 0..length {
65-
let data = self.document.arena.get(node).unwrap();
66-
deleted_nodes.push(data.get().clone());
65+
let node_data = self.document.arena.get(node).unwrap();
66+
let data = node_data.get();
67+
deleted_nodes.push(NodeSubTree {
68+
node_type: data.node_type.clone(),
69+
attributes: data.attributes.clone(),
70+
delta: data.delta.clone(),
71+
children: vec![],
72+
});
6773
node = node.following_siblings(&self.document.arena).next().unwrap();
6874
}
6975

0 commit comments

Comments
 (0)