moduforge_model/ops/
shl.rs

1use std::ops::Shl;
2
3use crate::{error::PoolResult, node::Node};
4
5use super::{NodeRef};
6
7/// 为 NodeRef 实现自定义的 << 运算符,用于在子节点列表开头插入单个节点
8/// 当使用 << 运算符时,会将新节点插入到当前节点的子节点列表的开头位置
9impl<'a> Shl<Node> for NodeRef<'a> {
10    type Output = PoolResult<NodeRef<'a>>;
11    fn shl(
12        self,
13        node: Node,
14    ) -> Self::Output {
15        // 在索引0处插入节点(开头位置)
16        self.tree.add_at_index(&self.key.clone().into(), 0, &node)?;
17        Ok(NodeRef::new(self.tree, self.key.clone()))
18    }
19}
20
21/// 为 NodeRef 实现自定义的 << 运算符,用于在子节点列表开头插入多个节点
22/// 当使用 << 运算符时,会将多个新节点依次插入到当前节点的子节点列表的开头位置
23impl<'a> Shl<Vec<Node>> for NodeRef<'a> {
24    type Output = PoolResult<NodeRef<'a>>;
25    fn shl(
26        self,
27        nodes: Vec<Node>,
28    ) -> Self::Output {
29        // 反向插入,确保节点顺序正确
30        for (i, node) in nodes.into_iter().enumerate() {
31            self.tree.add_at_index(&self.key.clone().into(), i, &node)?;
32        }
33        Ok(NodeRef::new(self.tree, self.key.clone()))
34    }
35}
36
37/// 为 NodeRef 实现自定义的 << 运算符,用于在指定数量的位置处插入节点
38/// 当使用 << 运算符时,会将当前节点向左移动指定位置数
39impl<'a> Shl<usize> for NodeRef<'a> {
40    type Output = PoolResult<NodeRef<'a>>;
41    fn shl(
42        self,
43        positions: usize,
44    ) -> Self::Output {
45        // 获取当前节点在父节点中的位置
46        if let Some(parent) =
47            self.tree.get_parent_node(&self.key.clone().into())
48        {
49            let siblings = self.tree.children(&parent.id).unwrap_or_default();
50
51            if let Some(current_index) =
52                siblings.iter().position(|id| id.clone() == self.key)
53            {
54                // 计算新位置,不能小于0
55                let new_index = current_index.saturating_sub(positions);
56
57                // 如果位置有变化,执行移动
58                if new_index != current_index {
59                    //这里只需要修改  content 中的顺序就行,不需要删除和添加
60                    let mut node = self
61                        .tree
62                        .get_node(&self.key.clone().into())
63                        .unwrap()
64                        .as_ref()
65                        .clone();
66                    let mut content = node.content.clone();
67                    content.swap(current_index, new_index);
68                    node.content = content;
69                    self.tree.update_node(node)?;
70                }
71            }
72        }
73
74        Ok(NodeRef::new(self.tree, self.key.clone()))
75    }
76}