123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- use super::node_serde::*;
- use crate::core::NodeBody::Delta;
- use crate::core::{AttributeKey, AttributeValue, NodeAttributes, OperationTransform};
- use crate::errors::OTError;
- use crate::rich_text::RichTextDelta;
- use serde::{Deserialize, Serialize};
- #[derive(Default, Clone, Serialize, Deserialize, Eq, PartialEq)]
- pub struct NodeData {
- #[serde(rename = "type")]
- pub node_type: String,
- #[serde(skip_serializing_if = "NodeAttributes::is_empty")]
- #[serde(default)]
- pub attributes: NodeAttributes,
- #[serde(serialize_with = "serialize_body")]
- #[serde(deserialize_with = "deserialize_body")]
- #[serde(skip_serializing_if = "NodeBody::is_empty")]
- #[serde(default)]
- pub body: NodeBody,
- #[serde(skip_serializing_if = "Vec::is_empty")]
- #[serde(default)]
- pub children: Vec<NodeData>,
- }
- impl NodeData {
- pub fn new<T: ToString>(node_type: T) -> NodeData {
- NodeData {
- node_type: node_type.to_string(),
- ..Default::default()
- }
- }
- pub fn split(self) -> (Node, Vec<NodeData>) {
- let node = Node {
- node_type: self.node_type,
- body: self.body,
- attributes: self.attributes,
- };
- (node, self.children)
- }
- }
- /// Builder for [`NodeData`]
- pub struct NodeDataBuilder {
- node: NodeData,
- }
- impl NodeDataBuilder {
- pub fn new<T: ToString>(node_type: T) -> Self {
- Self {
- node: NodeData::new(node_type.to_string()),
- }
- }
- /// Appends a new node to the end of the builder's node children.
- pub fn add_node(mut self, node: NodeData) -> Self {
- self.node.children.push(node);
- self
- }
- /// Inserts attributes to the builder's node.
- ///
- /// The attributes will be replace if they shared the same key
- pub fn insert_attribute(mut self, key: AttributeKey, value: AttributeValue) -> Self {
- self.node.attributes.insert(key, value);
- self
- }
- /// Inserts a body to the builder's node
- pub fn insert_body(mut self, body: NodeBody) -> Self {
- self.node.body = body;
- self
- }
- /// Returns the builder's node
- pub fn build(self) -> NodeData {
- self.node
- }
- }
- /// NodeBody represents as the node's data.
- ///
- /// For the moment, the NodeBody can be Empty or Delta. We can extend
- /// the NodeBody by adding a new enum type.
- ///
- /// The NodeBody implements the [`OperationTransform`] trait which means it can perform
- /// compose, transform and invert.
- ///
- #[derive(Debug, Clone, PartialEq, Eq)]
- pub enum NodeBody {
- Empty,
- Delta(RichTextDelta),
- }
- impl std::default::Default for NodeBody {
- fn default() -> Self {
- NodeBody::Empty
- }
- }
- impl NodeBody {
- fn is_empty(&self) -> bool {
- match self {
- NodeBody::Empty => true,
- _ => false,
- }
- }
- }
- impl OperationTransform for NodeBody {
- /// Only the same enum variant can perform the compose operation.
- fn compose(&self, other: &Self) -> Result<Self, OTError>
- where
- Self: Sized,
- {
- match (self, other) {
- (Delta(a), Delta(b)) => a.compose(b).map(|delta| Delta(delta)),
- (NodeBody::Empty, NodeBody::Empty) => Ok(NodeBody::Empty),
- (l, r) => {
- let msg = format!("{:?} can not compose {:?}", l, r);
- Err(OTError::internal().context(msg))
- }
- }
- }
- /// Only the same enum variant can perform the transform operation.
- fn transform(&self, other: &Self) -> Result<(Self, Self), OTError>
- where
- Self: Sized,
- {
- match (self, other) {
- (Delta(l), Delta(r)) => l.transform(r).map(|(ta, tb)| (Delta(ta), Delta(tb))),
- (NodeBody::Empty, NodeBody::Empty) => Ok((NodeBody::Empty, NodeBody::Empty)),
- (l, r) => {
- let msg = format!("{:?} can not compose {:?}", l, r);
- Err(OTError::internal().context(msg))
- }
- }
- }
- /// Only the same enum variant can perform the invert operation.
- fn invert(&self, other: &Self) -> Self {
- match (self, other) {
- (Delta(l), Delta(r)) => Delta(l.invert(r)),
- (NodeBody::Empty, NodeBody::Empty) => NodeBody::Empty,
- (l, r) => {
- tracing::error!("{:?} can not compose {:?}", l, r);
- l.clone()
- }
- }
- }
- }
- /// Represents the changeset of the [`NodeBody`]
- ///
- /// Each NodeBody except the Empty should have its corresponding changeset variant.
- #[derive(Debug, Clone, Serialize, Deserialize)]
- #[serde(rename_all = "snake_case")]
- pub enum NodeBodyChangeset {
- Delta {
- delta: RichTextDelta,
- inverted: RichTextDelta,
- },
- }
- impl NodeBodyChangeset {
- pub fn inverted(&self) -> NodeBodyChangeset {
- match self {
- NodeBodyChangeset::Delta { delta, inverted } => NodeBodyChangeset::Delta {
- delta: inverted.clone(),
- inverted: delta.clone(),
- },
- }
- }
- }
- /// [`Node`] represents as a leaf in the [`NodeTree`].
- ///
- #[derive(Clone, Eq, PartialEq, Debug)]
- pub struct Node {
- pub node_type: String,
- pub body: NodeBody,
- pub attributes: NodeAttributes,
- }
- impl Node {
- pub fn new(node_type: &str) -> Node {
- Node {
- node_type: node_type.into(),
- attributes: NodeAttributes::new(),
- body: NodeBody::Empty,
- }
- }
- pub fn apply_body_changeset(&mut self, changeset: NodeBodyChangeset) {
- match changeset {
- NodeBodyChangeset::Delta { delta, inverted: _ } => match self.body.compose(&Delta(delta.clone())) {
- Ok(new_body) => self.body = new_body,
- Err(e) => tracing::error!("{:?}", e),
- },
- }
- }
- }
- impl std::convert::From<NodeData> for Node {
- fn from(node: NodeData) -> Self {
- Self {
- node_type: node.node_type,
- attributes: node.attributes,
- body: node.body,
- }
- }
- }
- impl std::convert::From<&NodeData> for Node {
- fn from(node: &NodeData) -> Self {
- Self {
- node_type: node.node_type.clone(),
- attributes: node.attributes.clone(),
- body: node.body.clone(),
- }
- }
- }
|