1use std::sync::Arc;
2
3use mf_model::{
4 node_definition::NodeTree, schema::Schema, tree::Tree, types::NodeId,
5};
6
7use crate::transform_error;
8
9use super::{
10 step::{Step, StepResult},
11 TransformResult,
12};
13use serde::{Deserialize, Serialize};
14#[derive(Debug, Serialize, Deserialize, Clone)]
16pub struct AddNodeStep {
17 pub parent_id: NodeId,
18 pub nodes: Vec<NodeTree>,
19}
20impl AddNodeStep {
21 pub fn new(
22 parent_id: NodeId,
23 nodes: Vec<NodeTree>,
24 ) -> Self {
25 AddNodeStep { parent_id, nodes }
26 }
27 pub fn collect_node_ids(node_enum: &NodeTree) -> Vec<NodeId> {
29 let mut ids: Vec<NodeId> = vec![node_enum.0.id.clone()];
30 for child in &node_enum.1 {
31 ids.extend(Self::collect_node_ids(child));
32 }
33 ids
34 }
35}
36impl Step for AddNodeStep {
37 fn name(&self) -> String {
38 "add_node_step".to_string()
39 }
40 fn apply(
41 &self,
42 dart: &mut Tree,
43 schema: Arc<Schema>,
44 ) -> TransformResult<StepResult> {
45 let _ = schema;
46 let result = dart.add(&self.parent_id, self.nodes.clone());
47 match result {
48 Ok(_) => Ok(StepResult::ok()),
49 Err(e) => Err(transform_error(e.to_string())),
50 }
51 }
52 fn serialize(&self) -> Option<Vec<u8>> {
53 serde_json::to_vec(self).ok()
54 }
55
56 fn invert(
57 &self,
58 _: &Arc<Tree>,
59 ) -> Option<Arc<dyn Step>> {
60 let mut all_node_ids = Vec::new();
62 for node_enum in &self.nodes {
63 all_node_ids.extend(Self::collect_node_ids(node_enum));
64 }
65
66 if !all_node_ids.is_empty() {
67 return Some(Arc::new(RemoveNodeStep::new(
68 self.parent_id.clone(),
69 all_node_ids,
70 )));
71 }
72 None
73 }
74}
75#[derive(Debug, Serialize, Deserialize, Clone)]
77pub struct RemoveNodeStep {
78 pub parent_id: NodeId,
79 pub node_ids: Vec<NodeId>,
80}
81impl RemoveNodeStep {
82 pub fn new(
83 parent_id: NodeId,
84 node_ids: Vec<NodeId>,
85 ) -> Self {
86 RemoveNodeStep { parent_id, node_ids }
87 }
88}
89impl Step for RemoveNodeStep {
90 fn name(&self) -> String {
91 "remove_node_step".to_string()
92 }
93 fn apply(
94 &self,
95 dart: &mut Tree,
96 schema: Arc<Schema>,
97 ) -> TransformResult<StepResult> {
98 let _ = schema;
99 let result = dart.remove_node(&self.parent_id, self.node_ids.clone());
100 match result {
101 Ok(_) => Ok(StepResult::ok()),
102 Err(e) => Err(transform_error(e.to_string())), }
104 }
105 fn serialize(&self) -> Option<Vec<u8>> {
106 serde_json::to_vec(self).ok()
107 }
108
109 fn invert(
110 &self,
111 dart: &Arc<Tree>,
112 ) -> Option<Arc<dyn Step>> {
113 let mut nodes_to_restore = Vec::new();
115
116 for node_id in &self.node_ids {
117 if let Some(node_enum) = dart.all_children(node_id, None) {
118 nodes_to_restore.push(node_enum);
119 }
120 }
121
122 if !nodes_to_restore.is_empty() {
123 Some(Arc::new(AddNodeStep::new(
124 self.parent_id.clone(),
125 nodes_to_restore,
126 )))
127 } else {
128 None
129 }
130 }
131}
132
133#[derive(Debug, Serialize, Deserialize, Clone)]
134pub struct MoveNodeStep {
135 source_parent_id: NodeId,
136 target_parent_id: NodeId,
137 node_id: NodeId,
138 position: Option<usize>, }
140
141impl MoveNodeStep {
142 pub fn new(
143 source_parent_id: NodeId,
144 target_parent_id: NodeId,
145 node_id: NodeId,
146 position: Option<usize>,
147 ) -> Self {
148 MoveNodeStep { source_parent_id, target_parent_id, node_id, position }
149 }
150}
151
152impl Step for MoveNodeStep {
153 fn name(&self) -> String {
154 "move_node_step".to_string()
155 }
156 fn apply(
157 &self,
158 dart: &mut Tree,
159 schema: Arc<Schema>,
160 ) -> TransformResult<StepResult> {
161 let _ = schema;
162
163 match dart.move_node(
164 &self.source_parent_id,
165 &self.target_parent_id,
166 &self.node_id,
167 self.position,
168 ) {
169 Ok(()) => Ok(StepResult::ok()),
170 Err(err) => Err(transform_error(err.to_string())),
171 }
172 }
173 fn serialize(&self) -> Option<Vec<u8>> {
174 serde_json::to_vec(self).ok()
175 }
176
177 fn invert(
178 &self,
179 dart: &Arc<Tree>,
180 ) -> Option<Arc<dyn Step>> {
181 match dart.get_parent_node(&self.node_id) {
182 Some(source_parent) => {
183 let original_index = source_parent
185 .content
186 .iter()
187 .position(|id| id == &self.node_id);
188 let original_pos = original_index; Some(Arc::new(MoveNodeStep::new(
190 self.target_parent_id.clone(),
191 self.source_parent_id.clone(),
192 self.node_id.clone(),
193 original_pos,
194 )))
195 },
196 None => None,
197 }
198 }
199}
200
201#[cfg(test)]
202mod tests {
203 use super::*;
204 use mf_model::{
205 node::Node,
206 node_definition::{NodeTree, NodeSpec},
207 schema::{Schema, SchemaSpec},
208 tree::Tree,
209 attrs::Attrs,
210 };
211 use std::collections::HashMap;
212 use std::sync::Arc;
213
214 fn create_test_node(id: &str) -> Node {
215 Node::new(id, "test".to_string(), Attrs::default(), vec![], vec![])
216 }
217
218 fn create_test_schema() -> Arc<Schema> {
219 let mut nodes = HashMap::new();
220 nodes.insert(
221 "test".to_string(),
222 NodeSpec {
223 content: None,
224 marks: None,
225 group: None,
226 desc: Some("Test node".to_string()),
227 attrs: None,
228 },
229 );
230
231 let spec = SchemaSpec {
232 nodes,
233 marks: HashMap::new(),
234 top_node: Some("test".to_string()),
235 };
236
237 Arc::new(Schema::compile(spec).expect("测试 Schema 编译失败"))
238 }
239
240 fn create_test_tree() -> Tree {
241 let root = create_test_node("root");
242 Tree::new(root)
243 }
244
245 #[test]
246 fn test_add_node_step() {
247 let mut tree = create_test_tree();
248 let schema = create_test_schema();
249
250 let node = create_test_node("child");
252 let test = create_test_node("test");
253 let node_enum = NodeTree(node, vec![NodeTree(test, vec![])]);
254 let step = AddNodeStep::new("root".into(), vec![node_enum.clone()]);
255 let result = step.apply(&mut tree, schema.clone());
256 assert!(result.is_ok());
257
258 assert!(tree.get_node(&"test".into()).is_some());
260
261 let inverted = step.invert(&Arc::new(tree.clone()));
263 assert!(inverted.is_some());
264
265 if let Some(inverted_step) = inverted {
267 let result = inverted_step.apply(&mut tree, schema);
268 if result.is_err() {
269 eprintln!("Invert step failed: {result:?}");
270 }
271 assert!(result.is_ok());
272 assert!(tree.get_node(&"test".into()).is_none());
274 }
275 }
276
277 #[test]
278 fn test_remove_node_step() {
279 let mut tree = create_test_tree();
280 let schema = create_test_schema();
281
282 let node = create_test_node("test");
284 tree.add_node(&"root".into(), &vec![node])
285 .expect("测试中添加节点应该成功");
286
287 let step = RemoveNodeStep::new("root".into(), vec!["test".into()]);
288 let result = step.apply(&mut tree, schema.clone());
289 assert!(result.is_ok());
290
291 assert!(tree.get_node(&"test".into()).is_none());
293
294 let inverted = step.invert(&Arc::new(tree.clone()));
296 assert!(inverted.is_some());
297 }
298
299 #[test]
300 fn test_move_node_step() {
301 let mut tree = create_test_tree();
302 let schema = create_test_schema();
303
304 let source = create_test_node("source");
306 let target = create_test_node("target");
307 let node = create_test_node("node");
308
309 tree.add_node(&"root".into(), &vec![source])
310 .expect("测试中添加源节点应该成功");
311 tree.add_node(&"root".into(), &vec![target])
312 .expect("测试中添加目标节点应该成功");
313 tree.add_node(&"source".into(), &vec![node])
314 .expect("测试中添加子节点应该成功");
315
316 let step = MoveNodeStep::new(
317 "source".into(),
318 "target".into(),
319 "node".into(),
320 None,
321 );
322
323 let result = step.apply(&mut tree, schema.clone());
324 assert!(result.is_ok());
325
326 let target_node =
328 tree.get_node(&"target".into()).expect("目标节点应该存在");
329 assert!(target_node.content.contains(&"node".into()));
330
331 let inverted = step.invert(&Arc::new(tree.clone()));
333 assert!(inverted.is_some());
334 }
335}