feat: apply transactions

This commit is contained in:
Vincent Chan 2022-08-18 17:49:20 +08:00
parent ba160c8026
commit c207bf3679
6 changed files with 58 additions and 28 deletions

View File

@ -1,25 +1,25 @@
use crate::core::document::position::Position;
use crate::core::{DeleteOperation, DocumentOperation, InsertOperation, NodeAttributes, NodeData, TextEditOperation, Transaction, UpdateOperation};
use crate::core::{
DeleteOperation, DocumentOperation, InsertOperation, NodeAttributes, NodeData, TextEditOperation, Transaction,
UpdateOperation,
};
use indextree::{Arena, NodeId};
pub struct DocumentTree {
arena: Arena<NodeData>,
root: NodeId,
pub arena: Arena<NodeData>,
pub root: NodeId,
}
impl DocumentTree {
pub fn new() -> DocumentTree {
let mut arena = Arena::new();
let root = arena.new_node(NodeData::new("root".into()));
DocumentTree {
arena: Arena::new(),
root,
}
DocumentTree { arena, root }
}
pub fn node_at_path(&self, position: &Position) -> Option<NodeId> {
if position.is_empty() {
return None;
return Some(self.root);
}
let mut iterate_node = self.root;
@ -93,7 +93,7 @@ impl DocumentTree {
}
fn apply_op(&mut self, op: &DocumentOperation) {
match op {
match op {
DocumentOperation::Insert(op) => self.apply_insert(op),
DocumentOperation::Update(op) => self.apply_update(op),
DocumentOperation::Delete(op) => self.apply_delete(op),
@ -106,12 +106,18 @@ impl DocumentTree {
let last_index = op.path.0[op.path.0.len() - 1];
let parent_node = self.node_at_path(&Position(parent_path.to_vec()));
if let Some(parent_node) = parent_node {
self.insert_child_at_index(parent_node, last_index, &op.nodes);
let mut inserted_nodes = Vec::new();
for node in &op.nodes {
inserted_nodes.push(self.arena.new_node(node.clone()));
}
self.insert_child_at_index(parent_node, last_index, &inserted_nodes);
}
}
fn insert_child_at_index(&mut self, parent: NodeId, index: usize, insert_children: &[NodeId]) {
if index == 0 && insert_children.len() == 0 {
if index == 0 && parent.children(&self.arena).next().is_none() {
for id in insert_children {
parent.append(*id, &mut self.arena);
}

View File

@ -1,6 +1,5 @@
use crate::core::document::position::Position;
use crate::core::{NodeAttributes, TextDelta};
use indextree::NodeId;
use crate::core::{NodeAttributes, NodeData, TextDelta};
pub enum DocumentOperation {
Insert(InsertOperation),
@ -36,7 +35,7 @@ impl DocumentOperation {
pub struct InsertOperation {
pub path: Position,
pub nodes: Vec<NodeId>,
pub nodes: Vec<NodeData>,
}
pub struct UpdateOperation {
@ -47,7 +46,7 @@ pub struct UpdateOperation {
pub struct DeleteOperation {
pub path: Position,
pub nodes: Vec<NodeId>,
pub nodes: Vec<NodeData>,
}
pub struct TextEditOperation {

View File

@ -9,4 +9,5 @@ pub use attributes::*;
pub use document::*;
pub use document_operation::*;
pub use node::*;
pub use position::*;
pub use transaction::*;

View File

@ -1,6 +1,7 @@
use crate::core::{NodeAttributes, TextDelta};
use std::cell::RefCell;
use crate::core::{TextDelta, NodeAttributes};
#[derive(Clone)]
pub struct NodeData {
pub node_type: String,
pub attributes: RefCell<NodeAttributes>,

View File

@ -1,17 +1,14 @@
use crate::core::{DocumentOperation, DocumentTree};
use crate::core::document::position::Position;
use crate::core::{DeleteOperation, DocumentOperation, DocumentTree, InsertOperation, NodeData};
pub struct Transaction {
pub operations: Vec<DocumentOperation>,
}
impl Transaction {
fn new(operations: Vec<DocumentOperation>) -> Transaction {
Transaction {
operations,
}
Transaction { operations }
}
}
pub struct TransactionBuilder<'a> {
@ -23,17 +20,42 @@ impl<'a> TransactionBuilder<'a> {
pub fn new(document: &'a DocumentTree) -> TransactionBuilder {
TransactionBuilder {
document,
operations: Vec::new()
operations: Vec::new(),
}
}
pub fn insert_nodes(&mut self, path: &Position, nodes: &[NodeData]) {
self.push(DocumentOperation::Insert(InsertOperation {
path: path.clone(),
nodes: nodes.to_vec(),
}));
}
pub fn delete_node(&mut self, path: &Position) {
self.delete_nodes(path, 1);
}
pub fn delete_nodes(&mut self, path: &Position, length: usize) {
let mut node = self.document.node_at_path(path).unwrap();
let mut deleted_nodes: Vec<NodeData> = Vec::new();
for _ in 0..length {
let data = self.document.arena.get(node).unwrap();
deleted_nodes.push(data.get().clone());
node = node.following_siblings(&self.document.arena).next().unwrap();
}
self.operations.push(DocumentOperation::Delete(DeleteOperation {
path: path.clone(),
nodes: deleted_nodes,
}))
}
pub fn push(&mut self, op: DocumentOperation) {
self.operations.push(op);
}
pub fn finalize(self) -> Transaction {
Transaction {
operations: self.operations,
}
Transaction::new(self.operations)
}
}

View File

@ -1,4 +1,4 @@
use lib_ot::core::{DocumentTree, TransactionBuilder};
use lib_ot::core::{DocumentTree, NodeData, Position, TransactionBuilder};
#[test]
fn main() {
@ -9,7 +9,8 @@ fn main() {
#[test]
fn test_documents() {
let mut document = DocumentTree::new();
let tb = TransactionBuilder::new(&document);
let mut tb = TransactionBuilder::new(&document);
tb.insert_nodes(&Position(vec![0]), &vec![NodeData::new("type")]);
let transaction = tb.finalize();
document.apply(transaction);
}