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 =
18            self.tree.children(&self.key.clone().into()).unwrap_or_default();
19        let mut nodes_to_remove = Vec::new();
20
21        for child_id in children {
22            if let Some(node) = self.tree.get_node(&child_id) {
23                if node.r#type.to_string() != node_type {
24                    nodes_to_remove.push(child_id);
25                }
26            }
27        }
28
29        // 移除不匹配的节点
30        if !nodes_to_remove.is_empty() {
31            self.tree.remove_node(&self.key.clone().into(), nodes_to_remove)?;
32        }
33
34        Ok(NodeRef::new(self.tree, self.key.clone()))
35    }
36}
37
38/// 为 NodeRef 实现自定义的 & 运算符,用于保留多个指定类型的子节点
39/// 当使用 & 运算符时,会保留匹配任一指定类型的子节点,移除其他类型的子节点
40impl<'a> BitAnd<Vec<String>> for NodeRef<'a> {
41    type Output = PoolResult<NodeRef<'a>>;
42    fn bitand(
43        self,
44        node_types: Vec<String>,
45    ) -> Self::Output {
46        let children =
47            self.tree.children(&self.key.clone().into()).unwrap_or_default();
48        let mut nodes_to_remove = Vec::new();
49
50        for child_id in children {
51            if let Some(node) = self.tree.get_node(&child_id) {
52                let node_type_str = node.r#type.to_string();
53                if !node_types.contains(&node_type_str) {
54                    nodes_to_remove.push(child_id);
55                }
56            }
57        }
58
59        // 移除不匹配的节点
60        if !nodes_to_remove.is_empty() {
61            self.tree.remove_node(&self.key.clone().into(), nodes_to_remove)?;
62        }
63
64        Ok(NodeRef::new(self.tree, self.key.clone()))
65    }
66}
67
68/// 为 MarkRef 实现自定义的 & 运算符,用于保留指定名称的标记
69/// 当使用 & 运算符时,会保留指定名称的标记,移除其他标记
70impl<'a> BitAnd<String> for MarkRef<'a> {
71    type Output = PoolResult<MarkRef<'a>>;
72    fn bitand(
73        self,
74        mark_name: String,
75    ) -> Self::Output {
76        let noderef = self.tree.get_node(&self.key.clone().into());
77        match noderef {
78            Some(node) => {
79                let marks = node.marks.clone();
80                let mut marks_to_remove = Vec::new();
81                for mark in marks {
82                    if mark.r#type.to_string() != mark_name {
83                        marks_to_remove.push(mark);
84                    }
85                }
86
87                // 移除不匹配的标记
88                for mark in marks_to_remove {
89                    self.tree.remove_mark(&self.key.clone().into(), mark)?;
90                }
91                Ok(MarkRef::new(self.tree, self.key.clone()))
92            },
93            None => Err(error_helpers::node_not_found(self.key.clone().into())),
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}