From 745018cf2262defa0dde4176de85597e755f2118 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 10 Sep 2022 08:42:53 +0800 Subject: [PATCH] refactor: node attribute --- .../src/codec/markdown/markdown_encoder.rs | 52 +++--- shared-lib/lib-ot/src/core/delta/builder.rs | 8 +- shared-lib/lib-ot/src/core/delta/iterator.rs | 4 +- .../lib-ot/src/core/document/attributes.rs | 125 +++++++++++-- .../lib-ot/src/core/document/document.rs | 27 +-- .../src/core/document/document_operation.rs | 14 +- shared-lib/lib-ot/src/core/document/node.rs | 10 +- .../lib-ot/src/core/document/transaction.rs | 34 ++-- .../lib-ot/src/core/operation/builder.rs | 4 +- shared-lib/lib-ot/src/rich_text/attributes.rs | 172 +++++++++--------- .../lib-ot/src/rich_text/attributes_serde.rs | 90 +++++---- shared-lib/lib-ot/src/rich_text/builder.rs | 10 +- shared-lib/lib-ot/src/rich_text/delta.rs | 6 +- shared-lib/lib-ot/src/rich_text/macros.rs | 8 +- shared-lib/lib-ot/tests/node/script.rs | 8 +- shared-lib/lib-ot/tests/node/test.rs | 32 ++-- 16 files changed, 344 insertions(+), 260 deletions(-) diff --git a/shared-lib/lib-ot/src/codec/markdown/markdown_encoder.rs b/shared-lib/lib-ot/src/codec/markdown/markdown_encoder.rs index f338a029a4..82332792e5 100644 --- a/shared-lib/lib-ot/src/codec/markdown/markdown_encoder.rs +++ b/shared-lib/lib-ot/src/codec/markdown/markdown_encoder.rs @@ -1,5 +1,5 @@ use crate::core::{Delta, DeltaIterator}; -use crate::rich_text::{is_block, RichTextAttributeKey, RichTextAttributeValue, RichTextAttributes}; +use crate::rich_text::{is_block, TextAttributeKey, TextAttributeValue, TextAttributes}; use std::collections::HashMap; const LINEFEEDASCIICODE: i32 = 0x0A; @@ -98,14 +98,14 @@ mod tests { } struct Attribute { - key: RichTextAttributeKey, - value: RichTextAttributeValue, + key: TextAttributeKey, + value: TextAttributeValue, } -pub fn markdown_encoder(delta: &Delta) -> String { +pub fn markdown_encoder(delta: &Delta) -> String { let mut markdown_buffer = String::new(); let mut line_buffer = String::new(); - let mut current_inline_style = RichTextAttributes::default(); + let mut current_inline_style = TextAttributes::default(); let mut current_block_lines: Vec = Vec::new(); let mut iterator = DeltaIterator::new(delta); let mut current_block_style: Option = None; @@ -138,17 +138,17 @@ pub fn markdown_encoder(delta: &Delta) -> String { } fn handle_inline( - current_inline_style: &mut RichTextAttributes, + current_inline_style: &mut TextAttributes, buffer: &mut String, mut text: String, - attributes: RichTextAttributes, + attributes: TextAttributes, ) { - let mut marked_for_removal: HashMap = HashMap::new(); + let mut marked_for_removal: HashMap = HashMap::new(); for key in current_inline_style .clone() .keys() - .collect::>() + .collect::>() .into_iter() .rev() { @@ -205,46 +205,46 @@ fn trim_right(buffer: &mut String) -> String { " ".repeat(text.len() - result.len()) } -fn write_attribute(buffer: &mut String, key: &RichTextAttributeKey, value: &RichTextAttributeValue, close: bool) { +fn write_attribute(buffer: &mut String, key: &TextAttributeKey, value: &TextAttributeValue, close: bool) { match key { - RichTextAttributeKey::Bold => buffer.push_str("**"), - RichTextAttributeKey::Italic => buffer.push_str("_"), - RichTextAttributeKey::Underline => { + TextAttributeKey::Bold => buffer.push_str("**"), + TextAttributeKey::Italic => buffer.push_str("_"), + TextAttributeKey::Underline => { if close { buffer.push_str("") } else { buffer.push_str("") } } - RichTextAttributeKey::StrikeThrough => { + TextAttributeKey::StrikeThrough => { if close { buffer.push_str("~~") } else { buffer.push_str("~~") } } - RichTextAttributeKey::Link => { + TextAttributeKey::Link => { if close { buffer.push_str(format!("]({})", value.0.as_ref().unwrap()).as_str()) } else { buffer.push_str("[") } } - RichTextAttributeKey::Background => { + TextAttributeKey::Background => { if close { buffer.push_str("") } else { buffer.push_str("") } } - RichTextAttributeKey::CodeBlock => { + TextAttributeKey::CodeBlock => { if close { buffer.push_str("\n```") } else { buffer.push_str("```\n") } } - RichTextAttributeKey::InlineCode => { + TextAttributeKey::InlineCode => { if close { buffer.push_str("`") } else { @@ -259,10 +259,10 @@ fn handle_line( buffer: &mut String, markdown_buffer: &mut String, data: String, - attributes: RichTextAttributes, + attributes: TextAttributes, current_block_style: &mut Option, current_block_lines: &mut Vec, - current_inline_style: &mut RichTextAttributes, + current_inline_style: &mut TextAttributes, ) { let mut span = String::new(); for c in data.chars() { @@ -274,7 +274,7 @@ fn handle_line( current_inline_style, buffer, String::from(""), - RichTextAttributes::default(), + TextAttributes::default(), ); let line_block_key = attributes.keys().find(|key| { @@ -339,7 +339,7 @@ fn handle_block( markdown_buffer.push_str(¤t_block_lines.join("\n")); markdown_buffer.push('\n'); } - Some(block_style) if block_style.key == RichTextAttributeKey::CodeBlock => { + Some(block_style) if block_style.key == TextAttributeKey::CodeBlock => { write_attribute(markdown_buffer, &block_style.key, &block_style.value, false); markdown_buffer.push_str(¤t_block_lines.join("\n")); write_attribute(markdown_buffer, &block_style.key, &block_style.value, true); @@ -360,9 +360,9 @@ fn write_block_tag(buffer: &mut String, block: &Attribute, close: bool) { return; } - if block.key == RichTextAttributeKey::BlockQuote { + if block.key == TextAttributeKey::BlockQuote { buffer.push_str("> "); - } else if block.key == RichTextAttributeKey::List { + } else if block.key == TextAttributeKey::List { if block.value.0.as_ref().unwrap().eq("bullet") { buffer.push_str("* "); } else if block.value.0.as_ref().unwrap().eq("checked") { @@ -374,14 +374,14 @@ fn write_block_tag(buffer: &mut String, block: &Attribute, close: bool) { } else { buffer.push_str("* "); } - } else if block.key == RichTextAttributeKey::Header { + } else if block.key == TextAttributeKey::Header { if block.value.0.as_ref().unwrap().eq("1") { buffer.push_str("# "); } else if block.value.0.as_ref().unwrap().eq("2") { buffer.push_str("## "); } else if block.value.0.as_ref().unwrap().eq("3") { buffer.push_str("### "); - } else if block.key == RichTextAttributeKey::List { + } else if block.key == TextAttributeKey::List { } } } diff --git a/shared-lib/lib-ot/src/core/delta/builder.rs b/shared-lib/lib-ot/src/core/delta/builder.rs index 482b1ca8a9..d8bede927f 100644 --- a/shared-lib/lib-ot/src/core/delta/builder.rs +++ b/shared-lib/lib-ot/src/core/delta/builder.rs @@ -50,9 +50,9 @@ where /// # Examples /// /// ``` - /// use lib_ot::rich_text::{RichTextAttribute, RichTextDelta, RichTextDeltaBuilder}; + /// use lib_ot::rich_text::{TextAttribute, RichTextDelta, RichTextDeltaBuilder}; /// - /// let mut attribute = RichTextAttribute::Bold(true); + /// let mut attribute = TextAttribute::Bold(true); /// let delta = RichTextDeltaBuilder::new().retain_with_attributes(7, attribute.into()).build(); /// /// assert_eq!(delta.json_str(), r#"[{"retain":7,"attributes":{"bold":true}}]"#); @@ -109,7 +109,7 @@ where /// /// ``` /// use lib_ot::core::{OperationTransform, TextDeltaBuilder}; - /// use lib_ot::rich_text::{RichTextAttribute, RichTextDeltaBuilder}; + /// use lib_ot::rich_text::{TextAttribute, RichTextDeltaBuilder}; /// let delta = TextDeltaBuilder::new() /// .retain(3) /// .trim() @@ -117,7 +117,7 @@ where /// assert_eq!(delta.ops.len(), 0); /// /// let delta = RichTextDeltaBuilder::new() - /// .retain_with_attributes(3, RichTextAttribute::Bold(true).into()) + /// .retain_with_attributes(3, TextAttribute::Bold(true).into()) /// .trim() /// .build(); /// assert_eq!(delta.ops.len(), 1); diff --git a/shared-lib/lib-ot/src/core/delta/iterator.rs b/shared-lib/lib-ot/src/core/delta/iterator.rs index 7997d23bae..53fb4f879b 100644 --- a/shared-lib/lib-ot/src/core/delta/iterator.rs +++ b/shared-lib/lib-ot/src/core/delta/iterator.rs @@ -2,7 +2,7 @@ use super::cursor::*; use crate::core::delta::{Delta, NEW_LINE}; use crate::core::interval::Interval; use crate::core::operation::{Attributes, Operation}; -use crate::rich_text::RichTextAttributes; +use crate::rich_text::TextAttributes; use std::ops::{Deref, DerefMut}; pub(crate) const MAX_IV_LEN: usize = i32::MAX as usize; @@ -132,7 +132,7 @@ where } } -pub fn is_empty_line_at_index(delta: &Delta, index: usize) -> bool { +pub fn is_empty_line_at_index(delta: &Delta, index: usize) -> bool { let mut iter = DeltaIterator::new(delta); let (prev, next) = (iter.next_op_with_len(index), iter.next_op()); if prev.is_none() { diff --git a/shared-lib/lib-ot/src/core/document/attributes.rs b/shared-lib/lib-ot/src/core/document/attributes.rs index ca5878fb4b..5ad89fbee9 100644 --- a/shared-lib/lib-ot/src/core/document/attributes.rs +++ b/shared-lib/lib-ot/src/core/document/attributes.rs @@ -1,10 +1,12 @@ +use crate::core::OperationTransform; +use crate::errors::OTError; use serde::{Deserialize, Serialize}; use std::collections::HashMap; -pub type AttributeMap = HashMap>; +pub type AttributeMap = HashMap; #[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Debug)] -pub struct NodeAttributes(pub AttributeMap); +pub struct NodeAttributes(AttributeMap); impl Default for NodeAttributes { fn default() -> Self { @@ -31,19 +33,120 @@ impl NodeAttributes { NodeAttributes(HashMap::new()) } + pub fn from_value(attribute_map: AttributeMap) -> Self { + Self(attribute_map) + } + pub fn to_inner(&self) -> AttributeMap { self.0.clone() } - pub fn compose(a: &NodeAttributes, b: &NodeAttributes) -> NodeAttributes { - let mut new_map: AttributeMap = b.0.clone(); + pub fn insert>(&mut self, key: K, value: V) { + self.0.insert(key.to_string(), value.into()); + } - for (key, value) in &a.0 { - if b.0.contains_key(key.as_str()) { - new_map.insert(key.into(), value.clone()); - } - } - - NodeAttributes(new_map) + pub fn delete(&mut self, key: &AttributeKey) { + self.insert(key.clone(), AttributeValue(None)); + } +} + +impl OperationTransform for NodeAttributes { + fn compose(&self, other: &Self) -> Result + where + Self: Sized, + { + let mut attributes = self.clone(); + attributes.0.extend(other.clone().0); + Ok(attributes) + } + + fn transform(&self, other: &Self) -> Result<(Self, Self), OTError> + where + Self: Sized, + { + let a = self.iter().fold(NodeAttributes::new(), |mut new_attributes, (k, v)| { + if !other.contains_key(k) { + new_attributes.insert(k.clone(), v.clone()); + } + new_attributes + }); + + let b = other.iter().fold(NodeAttributes::new(), |mut new_attributes, (k, v)| { + if !self.contains_key(k) { + new_attributes.insert(k.clone(), v.clone()); + } + new_attributes + }); + + Ok((a, b)) + } + + fn invert(&self, other: &Self) -> Self { + let base_inverted = other.iter().fold(NodeAttributes::new(), |mut attributes, (k, v)| { + if other.get(k) != self.get(k) && self.contains_key(k) { + attributes.insert(k.clone(), v.clone()); + } + attributes + }); + + self.iter().fold(base_inverted, |mut attributes, (k, _)| { + if other.get(k) != self.get(k) && !other.contains_key(k) { + attributes.delete(k); + } + attributes + }) + } +} + +pub type AttributeKey = String; + +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct AttributeValue(pub Option); + +impl std::convert::From<&usize> for AttributeValue { + fn from(val: &usize) -> Self { + AttributeValue::from(*val) + } +} + +impl std::convert::From for AttributeValue { + fn from(val: usize) -> Self { + if val > 0_usize { + AttributeValue(Some(format!("{}", val))) + } else { + AttributeValue(None) + } + } +} + +impl std::convert::From<&str> for AttributeValue { + fn from(val: &str) -> Self { + val.to_owned().into() + } +} + +impl std::convert::From for AttributeValue { + fn from(val: String) -> Self { + if val.is_empty() { + AttributeValue(None) + } else { + AttributeValue(Some(val)) + } + } +} + +impl std::convert::From<&bool> for AttributeValue { + fn from(val: &bool) -> Self { + AttributeValue::from(*val) + } +} + +impl std::convert::From for AttributeValue { + fn from(val: bool) -> Self { + let val = match val { + true => Some("true".to_owned()), + false => None, + }; + AttributeValue(val) } } diff --git a/shared-lib/lib-ot/src/core/document/document.rs b/shared-lib/lib-ot/src/core/document/document.rs index 59758c7ca9..70c19030cb 100644 --- a/shared-lib/lib-ot/src/core/document/document.rs +++ b/shared-lib/lib-ot/src/core/document/document.rs @@ -1,7 +1,5 @@ use crate::core::document::position::Path; -use crate::core::{ - DocumentOperation, NodeAttributes, NodeData, NodeSubTree, OperationTransform, TextDelta, Transaction, -}; +use crate::core::{DocumentOperation, Node, NodeAttributes, NodeData, OperationTransform, TextDelta, Transaction}; use crate::errors::{ErrorBuilder, OTError, OTErrorCode}; use indextree::{Arena, Children, FollowingSiblings, NodeId}; @@ -28,8 +26,8 @@ impl DocumentTree { /// # Examples /// /// ``` - /// use lib_ot::core::{DocumentOperation, DocumentTree, NodeSubTree, Path}; - /// let nodes = vec![NodeSubTree::new("text")]; + /// use lib_ot::core::{DocumentOperation, DocumentTree, Node, Path}; + /// let nodes = vec![Node::new("text")]; /// let root_path: Path = vec![0].into(); /// let op = DocumentOperation::Insert {path: root_path.clone(),nodes }; /// @@ -96,8 +94,8 @@ impl DocumentTree { /// # Examples /// /// ``` - /// use lib_ot::core::{DocumentOperation, DocumentTree, NodeSubTree, Path}; - /// let node = NodeSubTree::new("text"); + /// use lib_ot::core::{DocumentOperation, DocumentTree, Node, Path}; + /// let node = Node::new("text"); /// let inserted_path: Path = vec![0].into(); /// /// let mut document = DocumentTree::new(); @@ -160,7 +158,7 @@ impl DocumentTree { } } - fn apply_insert(&mut self, path: &Path, nodes: &[NodeSubTree]) -> Result<(), OTError> { + fn apply_insert(&mut self, path: &Path, nodes: &[Node]) -> Result<(), OTError> { debug_assert!(!path.is_empty()); if path.is_empty() { return Err(OTErrorCode::PathIsEmpty.into()); @@ -175,12 +173,7 @@ impl DocumentTree { self.insert_child_at_index(parent_node, last_index, nodes) } - fn insert_child_at_index( - &mut self, - parent: NodeId, - index: usize, - insert_children: &[NodeSubTree], - ) -> Result<(), OTError> { + fn insert_child_at_index(&mut self, parent: NodeId, index: usize, insert_children: &[Node]) -> Result<(), OTError> { if index == 0 && parent.children(&self.arena).next().is_none() { self.append_subtree(&parent, insert_children); return Ok(()); @@ -200,7 +193,7 @@ impl DocumentTree { } // recursive append the subtrees to the node - fn append_subtree(&mut self, parent: &NodeId, insert_children: &[NodeSubTree]) { + fn append_subtree(&mut self, parent: &NodeId, insert_children: &[Node]) { for child in insert_children { let child_id = self.arena.new_node(child.to_node_data()); parent.append(child_id, &mut self.arena); @@ -209,7 +202,7 @@ impl DocumentTree { } } - fn insert_subtree_before(&mut self, before: &NodeId, insert_children: &[NodeSubTree]) { + fn insert_subtree_before(&mut self, before: &NodeId, insert_children: &[Node]) { for child in insert_children { let child_id = self.arena.new_node(child.to_node_data()); before.insert_before(child_id, &mut self.arena); @@ -225,7 +218,7 @@ impl DocumentTree { let node_data = self.arena.get_mut(update_node).unwrap(); let new_node = { let old_attributes = &node_data.get().attributes; - let new_attributes = NodeAttributes::compose(old_attributes, attributes); + let new_attributes = NodeAttributes::compose(old_attributes, attributes)?; NodeData { attributes: new_attributes, ..node_data.get().clone() diff --git a/shared-lib/lib-ot/src/core/document/document_operation.rs b/shared-lib/lib-ot/src/core/document/document_operation.rs index 6e34c8cb77..c162f39afe 100644 --- a/shared-lib/lib-ot/src/core/document/document_operation.rs +++ b/shared-lib/lib-ot/src/core/document/document_operation.rs @@ -1,11 +1,11 @@ use crate::core::document::position::Path; -use crate::core::{NodeAttributes, NodeSubTree, TextDelta}; +use crate::core::{Node, NodeAttributes, TextDelta}; #[derive(Clone, serde::Serialize, serde::Deserialize)] #[serde(tag = "op")] pub enum DocumentOperation { #[serde(rename = "insert")] - Insert { path: Path, nodes: Vec }, + Insert { path: Path, nodes: Vec }, #[serde(rename = "update")] Update { path: Path, @@ -14,7 +14,7 @@ pub enum DocumentOperation { old_attributes: NodeAttributes, }, #[serde(rename = "delete")] - Delete { path: Path, nodes: Vec }, + Delete { path: Path, nodes: Vec }, #[serde(rename = "text-edit")] TextEdit { path: Path, @@ -101,7 +101,7 @@ impl DocumentOperation { #[cfg(test)] mod tests { - use crate::core::{Delta, DocumentOperation, NodeAttributes, NodeSubTree, Path}; + use crate::core::{Delta, DocumentOperation, Node, NodeAttributes, Path}; #[test] fn test_transform_path_1() { @@ -155,7 +155,7 @@ mod tests { fn test_serialize_insert_operation() { let insert = DocumentOperation::Insert { path: Path(vec![0, 1]), - nodes: vec![NodeSubTree::new("text")], + nodes: vec![Node::new("text")], }; let result = serde_json::to_string(&insert).unwrap(); assert_eq!( @@ -168,11 +168,11 @@ mod tests { fn test_serialize_insert_sub_trees() { let insert = DocumentOperation::Insert { path: Path(vec![0, 1]), - nodes: vec![NodeSubTree { + nodes: vec![Node { note_type: "text".into(), attributes: NodeAttributes::new(), delta: None, - children: vec![NodeSubTree::new("text")], + children: vec![Node::new("text")], }], }; let result = serde_json::to_string(&insert).unwrap(); diff --git a/shared-lib/lib-ot/src/core/document/node.rs b/shared-lib/lib-ot/src/core/document/node.rs index 9115f656f4..82cc1ea4d7 100644 --- a/shared-lib/lib-ot/src/core/document/node.rs +++ b/shared-lib/lib-ot/src/core/document/node.rs @@ -19,7 +19,7 @@ impl NodeData { } #[derive(Clone, Serialize, Deserialize, Eq, PartialEq)] -pub struct NodeSubTree { +pub struct Node { #[serde(rename = "type")] pub note_type: String, @@ -29,12 +29,12 @@ pub struct NodeSubTree { pub delta: Option, #[serde(skip_serializing_if = "Vec::is_empty")] - pub children: Vec, + pub children: Vec, } -impl NodeSubTree { - pub fn new(node_type: &str) -> NodeSubTree { - NodeSubTree { +impl Node { + pub fn new(node_type: &str) -> Node { + Node { note_type: node_type.into(), attributes: NodeAttributes::new(), delta: None, diff --git a/shared-lib/lib-ot/src/core/document/transaction.rs b/shared-lib/lib-ot/src/core/document/transaction.rs index a99ab66dac..f26346fe18 100644 --- a/shared-lib/lib-ot/src/core/document/transaction.rs +++ b/shared-lib/lib-ot/src/core/document/transaction.rs @@ -1,5 +1,5 @@ use crate::core::document::position::Path; -use crate::core::{AttributeMap, DocumentOperation, DocumentTree, NodeAttributes, NodeSubTree}; +use crate::core::{AttributeValue, DocumentOperation, DocumentTree, Node, NodeAttributes}; use indextree::NodeId; pub struct Transaction { @@ -38,17 +38,17 @@ impl<'a> TransactionBuilder<'a> { /// // -- 0 (root) /// // 0 -- text_1 /// // 1 -- text_2 - /// use lib_ot::core::{DocumentTree, NodeSubTree, TransactionBuilder}; + /// use lib_ot::core::{DocumentTree, Node, TransactionBuilder}; /// let mut document = DocumentTree::new(); /// let transaction = TransactionBuilder::new(&document) - /// .insert_nodes_at_path(0,vec![ NodeSubTree::new("text_1"), NodeSubTree::new("text_2")]) + /// .insert_nodes_at_path(0,vec![ Node::new("text_1"), Node::new("text_2")]) /// .finalize(); /// document.apply(transaction).unwrap(); /// /// document.node_at_path(vec![0, 0]); /// ``` /// - pub fn insert_nodes_at_path>(self, path: T, nodes: Vec) -> Self { + pub fn insert_nodes_at_path>(self, path: T, nodes: Vec) -> Self { self.push(DocumentOperation::Insert { path: path.into(), nodes, @@ -68,36 +68,34 @@ impl<'a> TransactionBuilder<'a> { /// // 0 /// // -- 0 /// // |-- text - /// use lib_ot::core::{DocumentTree, NodeSubTree, TransactionBuilder}; + /// use lib_ot::core::{DocumentTree, Node, TransactionBuilder}; /// let mut document = DocumentTree::new(); /// let transaction = TransactionBuilder::new(&document) - /// .insert_node_at_path(0, NodeSubTree::new("text")) + /// .insert_node_at_path(0, Node::new("text")) /// .finalize(); /// document.apply(transaction).unwrap(); /// ``` /// - pub fn insert_node_at_path>(self, path: T, node: NodeSubTree) -> Self { + pub fn insert_node_at_path>(self, path: T, node: Node) -> Self { self.insert_nodes_at_path(path, vec![node]) } - pub fn update_attributes_at_path(self, path: &Path, attributes: AttributeMap) -> Self { - let mut old_attributes: AttributeMap = AttributeMap::new(); + pub fn update_attributes_at_path(self, path: &Path, attributes: NodeAttributes) -> Self { + let mut old_attributes = NodeAttributes::new(); let node = self.document.node_at_path(path).unwrap(); let node_data = self.document.get_node_data(node).unwrap(); for key in attributes.keys() { let old_attrs = &node_data.attributes; - let old_value = match old_attrs.0.get(key.as_str()) { - Some(value) => value.clone(), - None => None, - }; - old_attributes.insert(key.clone(), old_value); + if let Some(value) = old_attrs.get(key.as_str()) { + old_attributes.insert(key.clone(), value.clone()); + } } self.push(DocumentOperation::Update { path: path.clone(), - attributes: NodeAttributes(attributes), - old_attributes: NodeAttributes(old_attributes), + attributes, + old_attributes, }) } @@ -120,7 +118,7 @@ impl<'a> TransactionBuilder<'a> { self } - fn get_deleted_nodes(&self, node_id: NodeId) -> NodeSubTree { + fn get_deleted_nodes(&self, node_id: NodeId) -> Node { let node_data = self.document.get_node_data(node_id).unwrap(); let mut children = vec![]; @@ -128,7 +126,7 @@ impl<'a> TransactionBuilder<'a> { children.push(self.get_deleted_nodes(child_id)); }); - NodeSubTree { + Node { note_type: node_data.node_type.clone(), attributes: node_data.attributes.clone(), delta: node_data.delta.clone(), diff --git a/shared-lib/lib-ot/src/core/operation/builder.rs b/shared-lib/lib-ot/src/core/operation/builder.rs index c4f9cc8277..b5a06484eb 100644 --- a/shared-lib/lib-ot/src/core/operation/builder.rs +++ b/shared-lib/lib-ot/src/core/operation/builder.rs @@ -1,7 +1,7 @@ use crate::core::operation::{Attributes, Operation, PhantomAttributes}; -use crate::rich_text::RichTextAttributes; +use crate::rich_text::TextAttributes; -pub type RichTextOpBuilder = OperationsBuilder; +pub type RichTextOpBuilder = OperationsBuilder; pub type PlainTextOpBuilder = OperationsBuilder; #[derive(Default)] diff --git a/shared-lib/lib-ot/src/rich_text/attributes.rs b/shared-lib/lib-ot/src/rich_text/attributes.rs index be3b1bbf59..f862dab4f3 100644 --- a/shared-lib/lib-ot/src/rich_text/attributes.rs +++ b/shared-lib/lib-ot/src/rich_text/attributes.rs @@ -10,19 +10,19 @@ use std::{ }; use strum_macros::Display; -pub type RichTextOperation = Operation; +pub type RichTextOperation = Operation; impl RichTextOperation { - pub fn contain_attribute(&self, attribute: &RichTextAttribute) -> bool { + pub fn contain_attribute(&self, attribute: &TextAttribute) -> bool { self.get_attributes().contains_key(&attribute.key) } } #[derive(Debug, Clone, Eq, PartialEq)] -pub struct RichTextAttributes { - pub(crate) inner: HashMap, +pub struct TextAttributes { + pub(crate) inner: HashMap, } -impl std::default::Default for RichTextAttributes { +impl std::default::Default for TextAttributes { fn default() -> Self { Self { inner: HashMap::with_capacity(0), @@ -30,40 +30,40 @@ impl std::default::Default for RichTextAttributes { } } -impl fmt::Display for RichTextAttributes { +impl fmt::Display for TextAttributes { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_fmt(format_args!("{:?}", self.inner)) } } #[inline(always)] -pub fn plain_attributes() -> RichTextAttributes { - RichTextAttributes::default() +pub fn plain_attributes() -> TextAttributes { + TextAttributes::default() } -impl RichTextAttributes { +impl TextAttributes { pub fn new() -> Self { - RichTextAttributes { inner: HashMap::new() } + TextAttributes { inner: HashMap::new() } } pub fn is_empty(&self) -> bool { self.inner.is_empty() } - pub fn add(&mut self, attribute: RichTextAttribute) { - let RichTextAttribute { key, value, scope: _ } = attribute; + pub fn add(&mut self, attribute: TextAttribute) { + let TextAttribute { key, value, scope: _ } = attribute; self.inner.insert(key, value); } - pub fn insert(&mut self, key: RichTextAttributeKey, value: RichTextAttributeValue) { + pub fn insert(&mut self, key: TextAttributeKey, value: TextAttributeValue) { self.inner.insert(key, value); } - pub fn delete(&mut self, key: &RichTextAttributeKey) { - self.inner.insert(key.clone(), RichTextAttributeValue(None)); + pub fn delete(&mut self, key: &TextAttributeKey) { + self.inner.insert(key.clone(), TextAttributeValue(None)); } - pub fn mark_all_as_removed_except(&mut self, attribute: Option) { + pub fn mark_all_as_removed_except(&mut self, attribute: Option) { match attribute { None => { self.inner.iter_mut().for_each(|(_k, v)| v.0 = None); @@ -78,7 +78,7 @@ impl RichTextAttributes { } } - pub fn remove(&mut self, key: RichTextAttributeKey) { + pub fn remove(&mut self, key: TextAttributeKey) { self.inner.retain(|k, _| k != &key); } @@ -95,7 +95,7 @@ impl RichTextAttributes { // Update inner by constructing new attributes from the other if it's // not None and replace the key/value with self key/value. - pub fn merge(&mut self, other: Option) { + pub fn merge(&mut self, other: Option) { if other.is_none() { return; } @@ -108,7 +108,7 @@ impl RichTextAttributes { } } -impl Attributes for RichTextAttributes { +impl Attributes for TextAttributes { fn is_empty(&self) -> bool { self.inner.is_empty() } @@ -122,7 +122,7 @@ impl Attributes for RichTextAttributes { } } -impl OperationTransform for RichTextAttributes { +impl OperationTransform for TextAttributes { fn compose(&self, other: &Self) -> Result where Self: Sized, @@ -136,29 +136,25 @@ impl OperationTransform for RichTextAttributes { where Self: Sized, { - let a = self - .iter() - .fold(RichTextAttributes::new(), |mut new_attributes, (k, v)| { - if !other.contains_key(k) { - new_attributes.insert(k.clone(), v.clone()); - } - new_attributes - }); + let a = self.iter().fold(TextAttributes::new(), |mut new_attributes, (k, v)| { + if !other.contains_key(k) { + new_attributes.insert(k.clone(), v.clone()); + } + new_attributes + }); - let b = other - .iter() - .fold(RichTextAttributes::new(), |mut new_attributes, (k, v)| { - if !self.contains_key(k) { - new_attributes.insert(k.clone(), v.clone()); - } - new_attributes - }); + let b = other.iter().fold(TextAttributes::new(), |mut new_attributes, (k, v)| { + if !self.contains_key(k) { + new_attributes.insert(k.clone(), v.clone()); + } + new_attributes + }); Ok((a, b)) } fn invert(&self, other: &Self) -> Self { - let base_inverted = other.iter().fold(RichTextAttributes::new(), |mut attributes, (k, v)| { + let base_inverted = other.iter().fold(TextAttributes::new(), |mut attributes, (k, v)| { if other.get(k) != self.get(k) && self.contains_key(k) { attributes.insert(k.clone(), v.clone()); } @@ -176,34 +172,34 @@ impl OperationTransform for RichTextAttributes { } } -impl std::ops::Deref for RichTextAttributes { - type Target = HashMap; +impl std::ops::Deref for TextAttributes { + type Target = HashMap; fn deref(&self) -> &Self::Target { &self.inner } } -impl std::ops::DerefMut for RichTextAttributes { +impl std::ops::DerefMut for TextAttributes { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.inner } } -pub fn attributes_except_header(op: &RichTextOperation) -> RichTextAttributes { +pub fn attributes_except_header(op: &RichTextOperation) -> TextAttributes { let mut attributes = op.get_attributes(); - attributes.remove(RichTextAttributeKey::Header); + attributes.remove(TextAttributeKey::Header); attributes } #[derive(Debug, Clone)] -pub struct RichTextAttribute { - pub key: RichTextAttributeKey, - pub value: RichTextAttributeValue, +pub struct TextAttribute { + pub key: TextAttributeKey, + pub value: TextAttributeValue, pub scope: AttributeScope, } -impl RichTextAttribute { +impl TextAttribute { // inline inline_attribute!(Bold, bool); inline_attribute!(Italic, bool); @@ -245,16 +241,16 @@ impl RichTextAttribute { } } -impl fmt::Display for RichTextAttribute { +impl fmt::Display for TextAttribute { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { let s = format!("{:?}:{:?} {:?}", self.key, self.value.0, self.scope); f.write_str(&s) } } -impl std::convert::From for RichTextAttributes { - fn from(attr: RichTextAttribute) -> Self { - let mut attributes = RichTextAttributes::new(); +impl std::convert::From for TextAttributes { + fn from(attr: TextAttribute) -> Self { + let mut attributes = TextAttributes::new(); attributes.add(attr); attributes } @@ -263,7 +259,7 @@ impl std::convert::From for RichTextAttributes { #[derive(Clone, Debug, Display, Hash, Eq, PartialEq, serde::Serialize, serde::Deserialize)] // serde.rs/variant-attrs.html // #[serde(rename_all = "snake_case")] -pub enum RichTextAttributeKey { +pub enum TextAttributeKey { #[serde(rename = "bold")] Bold, #[serde(rename = "italic")] @@ -304,90 +300,90 @@ pub enum RichTextAttributeKey { // pub trait AttributeValueData<'a>: Serialize + Deserialize<'a> {} #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct RichTextAttributeValue(pub Option); +pub struct TextAttributeValue(pub Option); -impl std::convert::From<&usize> for RichTextAttributeValue { +impl std::convert::From<&usize> for TextAttributeValue { fn from(val: &usize) -> Self { - RichTextAttributeValue::from(*val) + TextAttributeValue::from(*val) } } -impl std::convert::From for RichTextAttributeValue { +impl std::convert::From for TextAttributeValue { fn from(val: usize) -> Self { if val > 0_usize { - RichTextAttributeValue(Some(format!("{}", val))) + TextAttributeValue(Some(format!("{}", val))) } else { - RichTextAttributeValue(None) + TextAttributeValue(None) } } } -impl std::convert::From<&str> for RichTextAttributeValue { +impl std::convert::From<&str> for TextAttributeValue { fn from(val: &str) -> Self { val.to_owned().into() } } -impl std::convert::From for RichTextAttributeValue { +impl std::convert::From for TextAttributeValue { fn from(val: String) -> Self { if val.is_empty() { - RichTextAttributeValue(None) + TextAttributeValue(None) } else { - RichTextAttributeValue(Some(val)) + TextAttributeValue(Some(val)) } } } -impl std::convert::From<&bool> for RichTextAttributeValue { +impl std::convert::From<&bool> for TextAttributeValue { fn from(val: &bool) -> Self { - RichTextAttributeValue::from(*val) + TextAttributeValue::from(*val) } } -impl std::convert::From for RichTextAttributeValue { +impl std::convert::From for TextAttributeValue { fn from(val: bool) -> Self { let val = match val { true => Some("true".to_owned()), false => None, }; - RichTextAttributeValue(val) + TextAttributeValue(val) } } -pub fn is_block_except_header(k: &RichTextAttributeKey) -> bool { - if k == &RichTextAttributeKey::Header { +pub fn is_block_except_header(k: &TextAttributeKey) -> bool { + if k == &TextAttributeKey::Header { return false; } BLOCK_KEYS.contains(k) } -pub fn is_block(k: &RichTextAttributeKey) -> bool { +pub fn is_block(k: &TextAttributeKey) -> bool { BLOCK_KEYS.contains(k) } lazy_static! { - static ref BLOCK_KEYS: HashSet = HashSet::from_iter(vec![ - RichTextAttributeKey::Header, - RichTextAttributeKey::Indent, - RichTextAttributeKey::Align, - RichTextAttributeKey::CodeBlock, - RichTextAttributeKey::List, - RichTextAttributeKey::BlockQuote, + static ref BLOCK_KEYS: HashSet = HashSet::from_iter(vec![ + TextAttributeKey::Header, + TextAttributeKey::Indent, + TextAttributeKey::Align, + TextAttributeKey::CodeBlock, + TextAttributeKey::List, + TextAttributeKey::BlockQuote, ]); - static ref INLINE_KEYS: HashSet = HashSet::from_iter(vec![ - RichTextAttributeKey::Bold, - RichTextAttributeKey::Italic, - RichTextAttributeKey::Underline, - RichTextAttributeKey::StrikeThrough, - RichTextAttributeKey::Link, - RichTextAttributeKey::Color, - RichTextAttributeKey::Font, - RichTextAttributeKey::Size, - RichTextAttributeKey::Background, - RichTextAttributeKey::InlineCode, + static ref INLINE_KEYS: HashSet = HashSet::from_iter(vec![ + TextAttributeKey::Bold, + TextAttributeKey::Italic, + TextAttributeKey::Underline, + TextAttributeKey::StrikeThrough, + TextAttributeKey::Link, + TextAttributeKey::Color, + TextAttributeKey::Font, + TextAttributeKey::Size, + TextAttributeKey::Background, + TextAttributeKey::InlineCode, ]); - static ref INGORE_KEYS: HashSet = - HashSet::from_iter(vec![RichTextAttributeKey::Width, RichTextAttributeKey::Height,]); + static ref INGORE_KEYS: HashSet = + HashSet::from_iter(vec![TextAttributeKey::Width, TextAttributeKey::Height,]); } #[derive(Debug, PartialEq, Eq, Clone)] diff --git a/shared-lib/lib-ot/src/rich_text/attributes_serde.rs b/shared-lib/lib-ot/src/rich_text/attributes_serde.rs index 19ffb5a416..42c8c73834 100644 --- a/shared-lib/lib-ot/src/rich_text/attributes_serde.rs +++ b/shared-lib/lib-ot/src/rich_text/attributes_serde.rs @@ -1,5 +1,5 @@ #[rustfmt::skip] -use crate::rich_text::{RichTextAttribute, RichTextAttributeKey, RichTextAttributes, RichTextAttributeValue}; +use crate::rich_text::{TextAttribute, TextAttributeKey, TextAttributes, TextAttributeValue}; use serde::{ de, de::{MapAccess, Visitor}, @@ -8,7 +8,7 @@ use serde::{ }; use std::fmt; -impl Serialize for RichTextAttribute { +impl Serialize for TextAttribute { fn serialize(&self, serializer: S) -> Result<::Ok, ::Error> where S: Serializer, @@ -19,7 +19,7 @@ impl Serialize for RichTextAttribute { } } -impl Serialize for RichTextAttributes { +impl Serialize for TextAttributes { fn serialize(&self, serializer: S) -> Result where S: Serializer, @@ -36,43 +36,39 @@ impl Serialize for RichTextAttributes { } } -fn serial_attribute( - map_serializer: &mut S, - key: &RichTextAttributeKey, - value: &RichTextAttributeValue, -) -> Result<(), E> +fn serial_attribute(map_serializer: &mut S, key: &TextAttributeKey, value: &TextAttributeValue) -> Result<(), E> where S: SerializeMap, E: From<::Error>, { if let Some(v) = &value.0 { match key { - RichTextAttributeKey::Bold - | RichTextAttributeKey::Italic - | RichTextAttributeKey::Underline - | RichTextAttributeKey::StrikeThrough - | RichTextAttributeKey::CodeBlock - | RichTextAttributeKey::InlineCode - | RichTextAttributeKey::BlockQuote => match &v.parse::() { + TextAttributeKey::Bold + | TextAttributeKey::Italic + | TextAttributeKey::Underline + | TextAttributeKey::StrikeThrough + | TextAttributeKey::CodeBlock + | TextAttributeKey::InlineCode + | TextAttributeKey::BlockQuote => match &v.parse::() { Ok(value) => map_serializer.serialize_entry(&key, value)?, Err(e) => log::error!("Serial {:?} failed. {:?}", &key, e), }, - RichTextAttributeKey::Font - | RichTextAttributeKey::Size - | RichTextAttributeKey::Header - | RichTextAttributeKey::Indent - | RichTextAttributeKey::Width - | RichTextAttributeKey::Height => match &v.parse::() { + TextAttributeKey::Font + | TextAttributeKey::Size + | TextAttributeKey::Header + | TextAttributeKey::Indent + | TextAttributeKey::Width + | TextAttributeKey::Height => match &v.parse::() { Ok(value) => map_serializer.serialize_entry(&key, value)?, Err(e) => log::error!("Serial {:?} failed. {:?}", &key, e), }, - RichTextAttributeKey::Link - | RichTextAttributeKey::Color - | RichTextAttributeKey::Background - | RichTextAttributeKey::Align - | RichTextAttributeKey::List => { + TextAttributeKey::Link + | TextAttributeKey::Color + | TextAttributeKey::Background + | TextAttributeKey::Align + | TextAttributeKey::List => { map_serializer.serialize_entry(&key, v)?; } } @@ -82,14 +78,14 @@ where Ok(()) } -impl<'de> Deserialize<'de> for RichTextAttributes { - fn deserialize(deserializer: D) -> Result +impl<'de> Deserialize<'de> for TextAttributes { + fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { struct AttributesVisitor; impl<'de> Visitor<'de> for AttributesVisitor { - type Value = RichTextAttributes; + type Value = TextAttributes; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("Expect map") } @@ -98,9 +94,9 @@ impl<'de> Deserialize<'de> for RichTextAttributes { where A: MapAccess<'de>, { - let mut attributes = RichTextAttributes::new(); - while let Some(key) = map.next_key::()? { - let value = map.next_value::()?; + let mut attributes = TextAttributes::new(); + while let Some(key) = map.next_key::()? { + let value = map.next_value::()?; attributes.insert(key, value); } @@ -111,7 +107,7 @@ impl<'de> Deserialize<'de> for RichTextAttributes { } } -impl Serialize for RichTextAttributeValue { +impl Serialize for TextAttributeValue { fn serialize(&self, serializer: S) -> Result where S: Serializer, @@ -123,14 +119,14 @@ impl Serialize for RichTextAttributeValue { } } -impl<'de> Deserialize<'de> for RichTextAttributeValue { - fn deserialize(deserializer: D) -> Result +impl<'de> Deserialize<'de> for TextAttributeValue { + fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { struct AttributeValueVisitor; impl<'de> Visitor<'de> for AttributeValueVisitor { - type Value = RichTextAttributeValue; + type Value = TextAttributeValue; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("bool, usize or string") } @@ -145,56 +141,56 @@ impl<'de> Deserialize<'de> for RichTextAttributeValue { where E: de::Error, { - Ok(RichTextAttributeValue(Some(format!("{}", value)))) + Ok(TextAttributeValue(Some(format!("{}", value)))) } fn visit_i16(self, value: i16) -> Result where E: de::Error, { - Ok(RichTextAttributeValue(Some(format!("{}", value)))) + Ok(TextAttributeValue(Some(format!("{}", value)))) } fn visit_i32(self, value: i32) -> Result where E: de::Error, { - Ok(RichTextAttributeValue(Some(format!("{}", value)))) + Ok(TextAttributeValue(Some(format!("{}", value)))) } fn visit_i64(self, value: i64) -> Result where E: de::Error, { - Ok(RichTextAttributeValue(Some(format!("{}", value)))) + Ok(TextAttributeValue(Some(format!("{}", value)))) } fn visit_u8(self, value: u8) -> Result where E: de::Error, { - Ok(RichTextAttributeValue(Some(format!("{}", value)))) + Ok(TextAttributeValue(Some(format!("{}", value)))) } fn visit_u16(self, value: u16) -> Result where E: de::Error, { - Ok(RichTextAttributeValue(Some(format!("{}", value)))) + Ok(TextAttributeValue(Some(format!("{}", value)))) } fn visit_u32(self, value: u32) -> Result where E: de::Error, { - Ok(RichTextAttributeValue(Some(format!("{}", value)))) + Ok(TextAttributeValue(Some(format!("{}", value)))) } fn visit_u64(self, value: u64) -> Result where E: de::Error, { - Ok(RichTextAttributeValue(Some(format!("{}", value)))) + Ok(TextAttributeValue(Some(format!("{}", value)))) } fn visit_str(self, s: &str) -> Result @@ -208,7 +204,7 @@ impl<'de> Deserialize<'de> for RichTextAttributeValue { where E: de::Error, { - Ok(RichTextAttributeValue(None)) + Ok(TextAttributeValue(None)) } fn visit_unit(self) -> Result @@ -216,7 +212,7 @@ impl<'de> Deserialize<'de> for RichTextAttributeValue { E: de::Error, { // the value that contains null will be processed here. - Ok(RichTextAttributeValue(None)) + Ok(TextAttributeValue(None)) } fn visit_map(self, map: A) -> Result @@ -225,7 +221,7 @@ impl<'de> Deserialize<'de> for RichTextAttributeValue { { // https://github.com/serde-rs/json/issues/505 let mut map = map; - let value = map.next_value::()?; + let value = map.next_value::()?; Ok(value) } } diff --git a/shared-lib/lib-ot/src/rich_text/builder.rs b/shared-lib/lib-ot/src/rich_text/builder.rs index 84f3f09cfe..cc0a4e4370 100644 --- a/shared-lib/lib-ot/src/rich_text/builder.rs +++ b/shared-lib/lib-ot/src/rich_text/builder.rs @@ -1,15 +1,15 @@ #![allow(non_snake_case)] #![allow(clippy::derivable_impls)] -use crate::rich_text::{RichTextAttribute, RichTextAttributes}; +use crate::rich_text::{TextAttribute, TextAttributes}; pub struct AttributeBuilder { - inner: RichTextAttributes, + inner: TextAttributes, } impl std::default::Default for AttributeBuilder { fn default() -> Self { Self { - inner: RichTextAttributes::default(), + inner: TextAttributes::default(), } } } @@ -19,12 +19,12 @@ impl AttributeBuilder { AttributeBuilder::default() } - pub fn add_attr(mut self, attribute: RichTextAttribute) -> Self { + pub fn add_attr(mut self, attribute: TextAttribute) -> Self { self.inner.add(attribute); self } - pub fn build(self) -> RichTextAttributes { + pub fn build(self) -> TextAttributes { self.inner } } diff --git a/shared-lib/lib-ot/src/rich_text/delta.rs b/shared-lib/lib-ot/src/rich_text/delta.rs index 3a60cf7b02..f00d29e72a 100644 --- a/shared-lib/lib-ot/src/rich_text/delta.rs +++ b/shared-lib/lib-ot/src/rich_text/delta.rs @@ -1,5 +1,5 @@ use crate::core::{Delta, DeltaBuilder}; -use crate::rich_text::RichTextAttributes; +use crate::rich_text::TextAttributes; -pub type RichTextDelta = Delta; -pub type RichTextDeltaBuilder = DeltaBuilder; +pub type RichTextDelta = Delta; +pub type RichTextDeltaBuilder = DeltaBuilder; diff --git a/shared-lib/lib-ot/src/rich_text/macros.rs b/shared-lib/lib-ot/src/rich_text/macros.rs index 28fe903183..c8c396427d 100644 --- a/shared-lib/lib-ot/src/rich_text/macros.rs +++ b/shared-lib/lib-ot/src/rich_text/macros.rs @@ -6,7 +6,7 @@ macro_rules! inline_attribute { ) => { pub fn $key(value: $value) -> Self { Self { - key: RichTextAttributeKey::$key, + key: TextAttributeKey::$key, value: value.into(), scope: AttributeScope::Inline, } @@ -22,7 +22,7 @@ macro_rules! block_attribute { ) => { pub fn $key(value: $value) -> Self { Self { - key: RichTextAttributeKey::$key, + key: TextAttributeKey::$key, value: value.into(), scope: AttributeScope::Block, } @@ -41,7 +41,7 @@ macro_rules! list_attribute { true => $value, false => "", }; - RichTextAttribute::List(value) + TextAttribute::List(value) } }; } @@ -54,7 +54,7 @@ macro_rules! ignore_attribute { ) => { pub fn $key(value: $value) -> Self { Self { - key: RichTextAttributeKey::$key, + key: TextAttributeKey::$key, value: value.into(), scope: AttributeScope::Ignore, } diff --git a/shared-lib/lib-ot/tests/node/script.rs b/shared-lib/lib-ot/tests/node/script.rs index 34daca8d7c..781e537202 100644 --- a/shared-lib/lib-ot/tests/node/script.rs +++ b/shared-lib/lib-ot/tests/node/script.rs @@ -1,11 +1,11 @@ -use lib_ot::core::{DocumentTree, NodeAttributes, NodeSubTree, Path, TransactionBuilder}; +use lib_ot::core::{DocumentTree, Node, NodeAttributes, Path, TransactionBuilder}; pub enum NodeScript { - InsertNode { path: Path, node: NodeSubTree }, + InsertNode { path: Path, node: Node }, InsertAttributes { path: Path, attributes: NodeAttributes }, DeleteNode { path: Path }, AssertNumberOfChildrenAtPath { path: Option, len: usize }, - AssertNode { path: Path, expected: Option }, + AssertNode { path: Path, expected: Option }, } pub struct NodeTest { @@ -36,7 +36,7 @@ impl NodeTest { } NodeScript::InsertAttributes { path, attributes } => { let transaction = TransactionBuilder::new(&self.node_tree) - .update_attributes_at_path(&path, attributes.to_inner()) + .update_attributes_at_path(&path, attributes) .finalize(); self.node_tree.apply(transaction).unwrap(); } diff --git a/shared-lib/lib-ot/tests/node/test.rs b/shared-lib/lib-ot/tests/node/test.rs index d299b08714..aa15ff76a5 100644 --- a/shared-lib/lib-ot/tests/node/test.rs +++ b/shared-lib/lib-ot/tests/node/test.rs @@ -1,11 +1,11 @@ use crate::node::script::NodeScript::*; use crate::node::script::NodeTest; -use lib_ot::core::{NodeAttributes, NodeSubTree, Path}; +use lib_ot::core::{Node, NodeAttributes, Path}; #[test] fn node_insert_test() { let mut test = NodeTest::new(); - let inserted_node = NodeSubTree::new("text"); + let inserted_node = Node::new("text"); let path: Path = 0.into(); let scripts = vec![ InsertNode { @@ -23,11 +23,11 @@ fn node_insert_test() { #[test] fn node_insert_node_with_children_test() { let mut test = NodeTest::new(); - let inserted_node = NodeSubTree { + let inserted_node = Node { note_type: "text".into(), attributes: NodeAttributes::new(), delta: None, - children: vec![NodeSubTree::new("image")], + children: vec![Node::new("image")], }; let path: Path = 0.into(); let scripts = vec![ @@ -47,13 +47,13 @@ fn node_insert_node_with_children_test() { fn node_insert_multi_nodes_test() { let mut test = NodeTest::new(); let path_1: Path = 0.into(); - let node_1 = NodeSubTree::new("text_1"); + let node_1 = Node::new("text_1"); let path_2: Path = 1.into(); - let node_2 = NodeSubTree::new("text_2"); + let node_2 = Node::new("text_2"); let path_3: Path = 2.into(); - let node_3 = NodeSubTree::new("text_3"); + let node_3 = Node::new("text_3"); let scripts = vec![ InsertNode { @@ -88,14 +88,14 @@ fn node_insert_multi_nodes_test() { fn node_insert_node_in_ordered_nodes_test() { let mut test = NodeTest::new(); let path_1: Path = 0.into(); - let node_1 = NodeSubTree::new("text_1"); + let node_1 = Node::new("text_1"); let path_2: Path = 1.into(); - let node_2_1 = NodeSubTree::new("text_2_1"); - let node_2_2 = NodeSubTree::new("text_2_2"); + let node_2_1 = Node::new("text_2_1"); + let node_2_2 = Node::new("text_2_2"); let path_3: Path = 2.into(); - let node_3 = NodeSubTree::new("text_3"); + let node_3 = Node::new("text_3"); let path_4: Path = 3.into(); @@ -143,11 +143,9 @@ fn node_insert_node_in_ordered_nodes_test() { fn node_insert_with_attributes_test() { let mut test = NodeTest::new(); let path: Path = 0.into(); - let mut inserted_node = NodeSubTree::new("text"); - inserted_node.attributes.insert("bold".to_string(), Some("true".into())); - inserted_node - .attributes - .insert("underline".to_string(), Some("true".into())); + let mut inserted_node = Node::new("text"); + inserted_node.attributes.insert("bold", true); + inserted_node.attributes.insert("underline", true); let scripts = vec![ InsertNode { @@ -169,7 +167,7 @@ fn node_insert_with_attributes_test() { #[test] fn node_delete_test() { let mut test = NodeTest::new(); - let inserted_node = NodeSubTree::new("text"); + let inserted_node = Node::new("text"); let path: Path = 0.into(); let scripts = vec![