moduforge_model/ops/
bitor.rs

1use std::ops::BitOr;
2
3use crate::{
4    error::PoolResult, id_generator::IdGenerator, mark::Mark, node::Node,
5    types::NodeId,
6};
7
8use super::{MarkRef, NodeRef};
9
10/// 为 NodeRef 实现自定义的 | 运算符,用于合并另一个节点的所有子节点
11/// 当使用 | 运算符时,会将另一个节点的所有子节点复制到当前节点中
12impl<'a> BitOr<NodeId> for NodeRef<'a> {
13    type Output = PoolResult<NodeRef<'a>>;
14    fn bitor(
15        self,
16        other_node_id: NodeId,
17    ) -> Self::Output {
18        // 获取另一个节点的所有子节点
19        let other_children =
20            self.tree.children(&other_node_id).unwrap_or_default();
21        let mut nodes_to_add = Vec::new();
22
23        for child_id in other_children {
24            if let Some(child_node) = self.tree.get_node(&child_id) {
25                let mut node = child_node.as_ref().clone();
26                node.id = IdGenerator::get_id();
27                nodes_to_add.push(node);
28            }
29        }
30
31        if !nodes_to_add.is_empty() {
32            self.tree.add_node(&self.key.clone().into(), &nodes_to_add)?;
33        }
34        Ok(NodeRef::new(self.tree, self.key.clone()))
35    }
36}
37
38/// 为 NodeRef 实现自定义的 | 运算符,用于合并多个节点的子节点
39/// 当使用 | 运算符时,会将多个节点的所有子节点复制到当前节点中
40impl<'a> BitOr<Vec<NodeId>> for NodeRef<'a> {
41    type Output = PoolResult<NodeRef<'a>>;
42    fn bitor(
43        self,
44        other_node_ids: Vec<NodeId>,
45    ) -> Self::Output {
46        let mut all_nodes_to_add = Vec::new();
47
48        for node_id in other_node_ids {
49            let children = self.tree.children(&node_id).unwrap_or_default();
50            for child_id in children {
51                if let Some(child_node) = self.tree.get_node(&child_id) {
52                    let mut node = child_node.as_ref().clone();
53                    node.id = IdGenerator::get_id();
54                    all_nodes_to_add.push(node);
55                }
56            }
57        }
58
59        if !all_nodes_to_add.is_empty() {
60            self.tree.add_node(&self.key.clone().into(), &all_nodes_to_add)?;
61        }
62
63        Ok(NodeRef::new(self.tree, self.key.clone()))
64    }
65}
66
67/// 为 NodeRef 实现自定义的 | 运算符,用于直接合并节点列表
68/// 当使用 | 运算符时,会将提供的节点列表合并到当前节点中
69impl<'a> BitOr<Vec<Node>> for NodeRef<'a> {
70    type Output = PoolResult<NodeRef<'a>>;
71    fn bitor(
72        self,
73        nodes: Vec<Node>,
74    ) -> Self::Output {
75        if !nodes.is_empty() {
76            self.tree.add_node(&self.key.clone().into(), &nodes)?;
77        }
78        Ok(NodeRef::new(self.tree, self.key.clone()))
79    }
80}
81
82/// 为 MarkRef 实现自定义的 | 运算符,用于合并标记(去重)
83/// 当使用 | 运算符时,会将新标记添加到当前标记列表中,如果标记已存在则不重复添加
84impl<'a> BitOr<Mark> for MarkRef<'a> {
85    type Output = PoolResult<MarkRef<'a>>;
86    fn bitor(
87        self,
88        mark: Mark,
89    ) -> Self::Output {
90        // 检查标记是否已存在
91        let existing_marks =
92            self.tree.get_marks(&self.key.clone().into()).unwrap_or_default();
93        let mark_exists = existing_marks.iter().any(|existing_mark| {
94            existing_mark.r#type == mark.r#type
95                && existing_mark.attrs == mark.attrs
96        });
97
98        if !mark_exists {
99            self.tree.add_mark(&self.key.clone().into(), &vec![mark])?;
100        }
101
102        Ok(MarkRef::new(self.tree, self.key.clone()))
103    }
104}
105
106/// 为 MarkRef 实现自定义的 | 运算符,用于合并多个标记(去重)
107/// 当使用 | 运算符时,会将多个新标记添加到当前标记列表中,自动去重
108impl<'a> BitOr<Vec<Mark>> for MarkRef<'a> {
109    type Output = PoolResult<MarkRef<'a>>;
110    fn bitor(
111        self,
112        marks: Vec<Mark>,
113    ) -> Self::Output {
114        let existing_marks =
115            self.tree.get_marks(&self.key.clone().into()).unwrap_or_default();
116        let mut unique_marks = Vec::new();
117
118        for mark in marks {
119            let mark_exists = existing_marks.iter().any(|existing_mark| {
120                existing_mark.r#type == mark.r#type
121                    && existing_mark.attrs == mark.attrs
122            });
123
124            if !mark_exists {
125                unique_marks.push(mark);
126            }
127        }
128
129        if !unique_marks.is_empty() {
130            self.tree.add_mark(&self.key.clone().into(), &unique_marks)?;
131        }
132
133        Ok(MarkRef::new(self.tree, self.key.clone()))
134    }
135}