moduforge_model/ops/
shl.rs

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