From 8401fa0983cd49dc4acb5ae22c5b27c2530ab8dc Mon Sep 17 00:00:00 2001 From: Vincent Chan Date: Thu, 18 Aug 2022 20:15:34 +0800 Subject: [PATCH] feat: update attributes --- .../lib-ot/src/core/document/attributes.rs | 2 +- .../lib-ot/src/core/document/transaction.rs | 24 ++++++++++++++++++- shared-lib/lib-ot/tests/main.rs | 15 +++++++++++- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/shared-lib/lib-ot/src/core/document/attributes.rs b/shared-lib/lib-ot/src/core/document/attributes.rs index 011c4cec43..b682fd8404 100644 --- a/shared-lib/lib-ot/src/core/document/attributes.rs +++ b/shared-lib/lib-ot/src/core/document/attributes.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; #[derive(Clone)] -pub struct NodeAttributes(HashMap>); +pub struct NodeAttributes(pub HashMap>); impl NodeAttributes { pub fn new() -> NodeAttributes { diff --git a/shared-lib/lib-ot/src/core/document/transaction.rs b/shared-lib/lib-ot/src/core/document/transaction.rs index 875b1bebdf..f240b8ea89 100644 --- a/shared-lib/lib-ot/src/core/document/transaction.rs +++ b/shared-lib/lib-ot/src/core/document/transaction.rs @@ -1,5 +1,6 @@ +use std::collections::HashMap; use crate::core::document::position::Position; -use crate::core::{DeleteOperation, DocumentOperation, DocumentTree, InsertOperation, NodeData}; +use crate::core::{DeleteOperation, DocumentOperation, DocumentTree, InsertOperation, NodeAttributes, NodeData, UpdateOperation}; pub struct Transaction { pub operations: Vec, @@ -31,6 +32,27 @@ impl<'a> TransactionBuilder<'a> { })); } + pub fn update_attributes(&mut self, path: &Position, attributes: HashMap>) { + let mut old_attributes: HashMap> = HashMap::new(); + let node = self.document.node_at_path(path).unwrap(); + let node_data = self.document.arena.get(node).unwrap().get(); + + for key in attributes.keys() { + let old_attrs = node_data.attributes.borrow(); + let old_value = match old_attrs.0.get(key.as_str()) { + Some(value) => value.clone(), + None => None, + }; + old_attributes.insert(key.clone(), old_value); + } + + self.push(DocumentOperation::Update(UpdateOperation { + path: path.clone(), + attributes: NodeAttributes(attributes), + old_attributes: NodeAttributes(old_attributes), + })) + } + pub fn delete_node(&mut self, path: &Position) { self.delete_nodes(path, 1); } diff --git a/shared-lib/lib-ot/tests/main.rs b/shared-lib/lib-ot/tests/main.rs index 8ed7c8a74e..2d1813f2c9 100644 --- a/shared-lib/lib-ot/tests/main.rs +++ b/shared-lib/lib-ot/tests/main.rs @@ -1,3 +1,4 @@ +use std::collections::HashMap; use lib_ot::core::{DocumentTree, NodeData, Position, TransactionBuilder}; #[test] @@ -10,7 +11,19 @@ fn main() { fn test_documents() { let mut document = DocumentTree::new(); let mut tb = TransactionBuilder::new(&document); - tb.insert_nodes(&Position(vec![0]), &vec![NodeData::new("type")]); + tb.insert_nodes(&Position(vec![0]), &vec![NodeData::new("text")]); + let transaction = tb.finalize(); + document.apply(transaction); + + assert!(document.node_at_path(&Position(vec![0])).is_some()); + let node = document.node_at_path(&Position(vec![0])).unwrap(); + let node_data = document.arena.get(node).unwrap().get(); + assert_eq!(node_data.node_type, "text"); + + let mut tb = TransactionBuilder::new(&document); + tb.update_attributes(&Position(vec![0]), HashMap::from([ + ("subtype".into(), Some("bullet-list".into())), + ])); let transaction = tb.finalize(); document.apply(transaction); }