mf_state/
transaction.rs

1use std::any::Any;
2use std::ops::{Deref, DerefMut};
3use std::sync::Arc;
4
5use async_trait::async_trait;
6use mf_model::mark::Mark;
7use mf_model::node_type::NodeEnum;
8use mf_model::types::NodeId;
9use mf_transform::TransformResult;
10use serde_json::Value;
11use uuid::Uuid;
12
13use super::state::State;
14use mf_model::node_pool::NodePool;
15use mf_transform::attr_step::AttrStep;
16use mf_transform::node_step::{AddNodeStep, RemoveNodeStep};
17use mf_transform::mark_step::{AddMarkStep, RemoveMarkStep};
18use mf_transform::transform::{Transform};
19use std::fmt::Debug;
20
21/// 定义可执行的命令接口
22/// 要求实现 Send + Sync 以支持并发操作,并实现 Debug 以支持调试
23#[async_trait]
24pub trait Command: Send + Sync + Debug {
25    async fn execute(
26        &self,
27        tr: &mut Transaction,
28    ) -> TransformResult<()>;
29    fn name(&self) -> String;
30}
31/// 事务结构体,用于管理文档的修改操作
32#[derive(Clone)]
33pub struct Transaction {
34    /// 存储元数据的哈希表,支持任意类型数据
35    pub meta: imbl::HashMap<String, Arc<dyn Any + Send + Sync>>,
36    /// 事务的唯一标识符(UUID v4)
37    pub id: Uuid,
38    transform: Transform,
39}
40impl Debug for Transaction {
41    fn fmt(
42        &self,
43        f: &mut std::fmt::Formatter<'_>,
44    ) -> std::fmt::Result {
45        write!(f, "Transaction {{ id: {}}}", self.id)
46    }
47}
48
49impl Deref for Transaction {
50    type Target = Transform;
51
52    fn deref(&self) -> &Self::Target {
53        &self.transform
54    }
55}
56
57impl DerefMut for Transaction {
58    fn deref_mut(&mut self) -> &mut Self::Target {
59        &mut self.transform
60    }
61}
62
63impl Transaction {
64    /// 创建新的事务实例
65    /// state: 当前状态对象
66    /// 返回: Transaction 实例
67    pub fn new(state: &State) -> Self {
68        let node = state.doc();
69        let schema = state.schema();
70        Transaction {
71            meta: imbl::HashMap::new(),
72            id: Uuid::new_v4(), // ✅ 使用 UUID v4 生成唯一标识
73            transform: Transform::new(node, schema),
74        }
75    }
76    pub fn merge(
77        &mut self,
78        other: &mut Self,
79    ) {
80        // 使用批量应用来优化性能
81        let steps_to_apply: Vec<_> = other.steps.iter().cloned().collect();
82        if let Err(e) = self.apply_steps_batch(steps_to_apply) {
83            eprintln!("批量应用步骤失败: {e}");
84        }
85    }
86    /// 获取当前文档状态
87    pub fn doc(&self) -> Arc<NodePool> {
88        self.transform.doc()
89    }
90    /// 设置节点属性
91    /// id: 节点ID
92    /// values: 属性键值对
93    pub fn set_node_attribute(
94        &mut self,
95        id: NodeId,
96        values: imbl::HashMap<String, Value>,
97    ) -> TransformResult<()> {
98        self.step(Arc::new(AttrStep::new(id, values)))?;
99        Ok(())
100    }
101    /// 添加新节点
102    /// parent_id: 父节点ID
103    /// node: 要添加的节点
104    pub fn add_node(
105        &mut self,
106        parent_id: NodeId,
107        nodes: Vec<NodeEnum>,
108    ) -> TransformResult<()> {
109        self.step(Arc::new(AddNodeStep::new(parent_id, nodes)))?;
110        Ok(())
111    }
112    /// 删除节点
113    /// id: 节点ID
114    /// nodes: 要删除的节点
115    pub fn remove_node(
116        &mut self,
117        parent_id: NodeId,
118        node_ids: Vec<NodeId>,
119    ) -> TransformResult<()> {
120        self.step(Arc::new(RemoveNodeStep::new(parent_id, node_ids)))?;
121        Ok(())
122    }
123    /// 添加标记
124    /// id: 节点ID
125    /// marks: 要添加的标记
126    pub fn add_mark(
127        &mut self,
128        id: NodeId,
129        marks: Vec<Mark>,
130    ) -> TransformResult<()> {
131        self.step(Arc::new(AddMarkStep::new(id, marks)))?;
132        Ok(())
133    }
134    /// 删除标记
135    /// id: 节点ID
136    /// marks: 要删除的标记
137    pub fn remove_mark(
138        &mut self,
139        id: NodeId,
140        mark_types: Vec<String>,
141    ) -> TransformResult<()> {
142        self.step(Arc::new(RemoveMarkStep::new(id, mark_types)))?;
143        Ok(())
144    }
145    /// 设置元数据
146    /// key: 键
147    /// value: 值(支持任意类型)
148    pub fn set_meta<K, T: Send + Sync + 'static>(
149        &mut self,
150        key: K,
151        value: T,
152    ) -> &mut Self
153    where
154        K: Into<String>,
155    {
156        let key_str = key.into();
157        self.meta.insert(key_str, Arc::new(value));
158        self
159    }
160    /// 获取元数据
161    /// key: 键
162    /// 返回: Option<&T>,如果存在且类型匹配则返回Some,否则返回None
163    pub fn get_meta<T: Clone + 'static>(
164        &self,
165        key: &str,
166    ) -> Option<T> {
167        let value = self.meta.get(key)?;
168
169        value.downcast_ref::<T>().cloned()
170    }
171}