wolf_graph/
elements.rs

1use std::collections::BTreeSet;
2
3use crate::{EdgeID, NodeID};
4
5/// A set of node identifiers.
6pub type Nodes = BTreeSet<NodeID>;
7
8/// A set of edge identifiers.
9pub type Edges = BTreeSet<EdgeID>;
10
11/// An identifier for either a node or an edge.
12#[derive(Debug, Clone, PartialEq, Eq, Hash)]
13pub enum ElementID {
14    Node(NodeID),
15    Edge(EdgeID),
16}
17
18/// A set of elment (node and edge) identifiers.
19#[derive(Debug, Clone, PartialEq, Eq, Hash)]
20pub struct Elements {
21    pub nodes: Nodes,
22    pub edges: Edges,
23}
24
25impl Elements {
26    pub fn new(nodes: Nodes, edges: Edges) -> Self {
27        Self { nodes, edges }
28    }
29
30    pub fn from_nodes(nodes: Nodes) -> Self {
31        Self::new(nodes, Edges::new())
32    }
33
34    pub fn from_edges(edges: Edges) -> Self {
35        Self::new(Nodes::new(), edges)
36    }
37
38    // Equivalent to Swift's `ExpressibleByArrayLiteral`
39    pub fn from_elements(elements: &[ElementID]) -> Self {
40        let nodes = elements
41            .iter()
42            .filter_map(|element| match element {
43                ElementID::Node(node) => Some(node),
44                _ => None,
45            })
46            .cloned()
47            .collect();
48        let edges = elements
49            .iter()
50            .filter_map(|element| match element {
51                ElementID::Edge(edge) => Some(edge),
52                _ => None,
53            })
54            .cloned()
55            .collect();
56        Self::new(nodes, edges)
57    }
58}
59
60impl Default for Elements {
61    fn default() -> Self {
62        Self::new(Nodes::new(), Edges::new())
63    }
64}
65
66impl From<Nodes> for Elements {
67    fn from(nodes: Nodes) -> Self {
68        Self::from_nodes(nodes)
69    }
70}
71
72impl From<Edges> for Elements {
73    fn from(edges: Edges) -> Self {
74        Self::from_edges(edges)
75    }
76}
77
78impl From<(Nodes, Edges)> for Elements {
79    fn from((nodes, edges): (Nodes, Edges)) -> Self {
80        Self::new(nodes, edges)
81    }
82}
83
84impl From<&Elements> for Elements {
85    fn from(elements: &Elements) -> Self {
86        elements.clone()
87    }
88}
89
90impl Elements {
91    /// Returns `true` if the set contains an element equal to the value.
92    pub fn contains(&self, member: &ElementID) -> bool {
93        match member {
94            ElementID::Node(node) => self.nodes.contains(node),
95            ElementID::Edge(edge) => self.edges.contains(edge),
96        }
97    }
98
99    /// Inserts a value into the set, returning `true` if the value was not present in the set.
100    pub fn insert(&mut self, new_member: ElementID) -> bool {
101        match new_member {
102            ElementID::Node(node) => self.nodes.insert(node),
103            ElementID::Edge(edge) => self.edges.insert(edge),
104        }
105    }
106
107    /// Inserts all the elements from `other` into `self`.
108    pub fn insert_all(&mut self, other: &Elements) {
109        self.nodes.extend(other.nodes.iter().cloned());
110        self.edges.extend(other.edges.iter().cloned());
111    }
112
113    /// Removes a value from the set, returning the value if it was present in the set.
114    pub fn remove(&mut self, member: &ElementID) -> bool {
115        match member {
116            ElementID::Node(node) => self.nodes.remove(node),
117            ElementID::Edge(edge) => self.edges.remove(edge),
118        }
119    }
120
121    /// Removes all the elements in `other` from `self`.
122    pub fn remove_all(&mut self, other: &Elements) {
123        self.nodes = self.nodes.difference(&other.nodes).cloned().collect();
124        self.edges = self.edges.difference(&other.edges).cloned().collect();
125    }
126
127    /// Returns the elements representing the union, i.e., all the elements in `self` or `other`.
128    pub fn union(&self, other: &Elements) -> Elements {
129        Elements::new(
130            self.nodes.union(&other.nodes).cloned().collect(),
131            self.edges.union(&other.edges).cloned().collect()
132        )
133    }
134
135    /// Returns the elements representing the intersection, i.e., all the elements in both `self` and `other`.
136    pub fn intersection(&self, other: &Elements) -> Elements {
137        Elements::new(
138            self.nodes.intersection(&other.nodes).cloned().collect(),
139            self.edges.intersection(&other.edges).cloned().collect()
140        )
141    }
142
143    /// Returns the elements representing the difference, i.e., all the elements in `self` but not in `other`.
144    pub fn difference(&self, other: &Elements) -> Elements {
145        Elements::new(
146            self.nodes.difference(&other.nodes).cloned().collect(),
147            self.edges.difference(&other.edges).cloned().collect()
148        )
149    }
150
151    /// Returns the elements representing the symmetric difference, i.e., all the elements in `self` or `other`, but not in both.
152    pub fn symmetric_difference(&self, other: &Elements) -> Elements {
153        Elements::new(
154            self.nodes.symmetric_difference(&other.nodes).cloned().collect(),
155            self.edges.symmetric_difference(&other.edges).cloned().collect()
156        )
157    }
158
159    /// Updates `self` with the union of `self` and `other`.
160    pub fn form_union(&mut self, other: &Elements) {
161        self.nodes = self.nodes.union(&other.nodes).cloned().collect();
162        self.edges = self.edges.union(&other.edges).cloned().collect();
163    }
164
165    /// Updates `self` with the intersection of `self` and `other`.
166    pub fn form_intersection(&mut self, other: &Elements) {
167        self.nodes = self.nodes.intersection(&other.nodes).cloned().collect();
168        self.edges = self.edges.intersection(&other.edges).cloned().collect();
169    }
170
171    /// Updates `self` with the difference of `self` and `other`.
172    pub fn form_difference(&mut self, other: &Elements) {
173        self.nodes = self.nodes.difference(&other.nodes).cloned().collect();
174        self.edges = self.edges.difference(&other.edges).cloned().collect();
175    }
176
177    /// Updates `self` with the symmetric difference of `self` and `other`.
178    pub fn form_symmetric_difference(&mut self, other: &Elements) {
179        self.nodes = self.nodes.symmetric_difference
180            (&other.nodes).cloned().collect();
181        self.edges = self.edges.symmetric_difference
182            (&other.edges).cloned().collect();
183    }
184
185    /// Returns true if `self` has no elements in common with `other`. This is equivalent to checking for an empty intersection.
186    pub fn is_disjoint(&self, other: &Elements) -> bool {
187        self.nodes.is_disjoint(&other.nodes) && self.edges.is_disjoint(&other.edges)
188    }
189
190    /// Returns true if `self` is a subset of `other`, i.e., `other` contains at least all the elements in `self`.
191    pub fn is_subset(&self, other: &Elements) -> bool {
192        self.nodes.is_subset(&other.nodes) && self.edges.is_subset(&other.edges)
193    }
194
195    /// Returns true if `self` is a superset of `other`, i.e., `self` contains at least all the elements in `other`.
196    pub fn is_superset(&self, other: &Elements) -> bool {
197        self.nodes.is_superset(&other.nodes) && self.edges.is_superset(&other.edges)
198    }
199
200    /// Returns the number of elements in `self`.
201    pub fn len(&self) -> usize {
202        self.nodes.len() + self.edges.len()
203    }
204
205    /// Returns `true` if the set contains no elements.
206    pub fn is_empty(&self) -> bool {
207        self.nodes.is_empty() && self.edges.is_empty()
208    }
209
210    /// Removes all elements from the set.
211    pub fn clear(&mut self) {
212        self.nodes.clear();
213        self.edges.clear();
214    }
215
216    /// Retains only the elements specified by the predicate.
217    pub fn retain<F>(&mut self, mut f: F)
218    where
219        F: FnMut(&ElementID) -> bool,
220    {
221        self.nodes.retain(|node| f(&ElementID::Node(node.clone())));
222        self.edges.retain(|edge| f(&ElementID::Edge(edge.clone())));
223    }
224}