moduforge_model/ops/
bitand.rs

1use std::ops::BitAnd;
2
3use crate::{
4    error::{error_helpers, PoolResult}
5};
6
7use super::{MarkRef, NodeRef};
8
9/// 为 NodeRef 实现自定义的 & 运算符,用于过滤特定类型的子节点
10/// 当使用 & 运算符时,会保留指定类型的子节点,移除其他类型的子节点
11impl<'a> BitAnd<String> for NodeRef<'a> {
12    type Output = PoolResult<NodeRef<'a>>;
13    fn bitand(
14        self,
15        node_type: String,
16    ) -> Self::Output {
17        let children = self.tree.children(&self.key.clone().into()).unwrap_or_default();
18        let mut nodes_to_remove = Vec::new();
19        
20        for child_id in children {
21            if let Some(node) = self.tree.get_node(&child_id) {
22                if node.r#type.to_string() != node_type {
23                    nodes_to_remove.push(child_id);
24                }
25            }
26        }
27        
28        // 移除不匹配的节点
29        if !nodes_to_remove.is_empty() {
30            self.tree.remove_node(&self.key.clone().into(), nodes_to_remove)?;
31        }
32        
33        Ok(NodeRef::new(self.tree, self.key.clone()))
34    }
35}
36
37/// 为 NodeRef 实现自定义的 & 运算符,用于保留多个指定类型的子节点
38/// 当使用 & 运算符时,会保留匹配任一指定类型的子节点,移除其他类型的子节点
39impl<'a> BitAnd<Vec<String>> for NodeRef<'a> {
40    type Output = PoolResult<NodeRef<'a>>;
41    fn bitand(
42        self,
43        node_types: Vec<String>,
44    ) -> Self::Output {
45        let children = self.tree.children(&self.key.clone().into()).unwrap_or_default();
46        let mut nodes_to_remove = Vec::new();
47        
48        for child_id in children {
49            if let Some(node) = self.tree.get_node(&child_id) {
50                let node_type_str = node.r#type.to_string();
51                if !node_types.contains(&node_type_str) {
52                    nodes_to_remove.push(child_id);
53                }
54            }
55        }
56        
57        // 移除不匹配的节点
58        if !nodes_to_remove.is_empty() {
59            self.tree.remove_node(&self.key.clone().into(), nodes_to_remove)?;
60        }
61        
62        Ok(NodeRef::new(self.tree, self.key.clone()))
63    }
64}
65
66
67/// 为 MarkRef 实现自定义的 & 运算符,用于保留指定名称的标记
68/// 当使用 & 运算符时,会保留指定名称的标记,移除其他标记
69impl<'a> BitAnd<String> for MarkRef<'a> {
70    type Output = PoolResult<MarkRef<'a>>;
71    fn bitand(
72        self,
73        mark_name: String,
74    ) -> Self::Output {
75        let noderef = self.tree.get_node(&self.key.clone().into());
76        match noderef {
77            Some(node) => {
78                let marks = node.marks.clone();
79                let mut marks_to_remove = Vec::new();
80                for mark in marks {
81                    if mark.r#type.to_string() != mark_name {
82                        marks_to_remove.push(mark);
83                    }
84                }
85                
86                // 移除不匹配的标记
87                for mark in marks_to_remove {
88                    self.tree.remove_mark(&self.key.clone().into(), mark)?;
89                }
90                Ok(MarkRef::new(self.tree, self.key.clone()))
91            }
92            None => Err(error_helpers::node_not_found(self.key.clone().into())),
93        }
94    }
95}
96
97
98/// 为 MarkRef 实现自定义的 & 运算符,用于保留多个指定名称的标记
99/// 当使用 & 运算符时,会保留匹配任一指定名称的标记,移除其他标记
100impl<'a> BitAnd<Vec<String>> for MarkRef<'a> {
101    type Output = PoolResult<MarkRef<'a>>;
102    fn bitand(
103        self,
104        mark_names: Vec<String>,
105    ) -> Self::Output {
106        let noderef = self.tree.get_node(&self.key.clone().into());
107        match noderef {
108            Some(node) => {
109                let marks = node.marks.clone();
110                let mut marks_to_remove = Vec::new();
111                for mark in marks {
112                    if !mark_names.contains(&mark.r#type.to_string()) {
113                        marks_to_remove.push(mark);
114                    }
115                }
116                
117                // 移除不匹配的标记
118                for mark in marks_to_remove {
119                    self.tree.remove_mark(&self.key.clone().into(), mark)?;
120                }
121                Ok(MarkRef::new(self.tree, self.key.clone()))
122            }
123            None => Err(error_helpers::node_not_found(self.key.clone().into())),
124        }
125    }
126}