1use petgraph::stable_graph::{EdgeIndex, NodeIndex, StableGraph};
8use petgraph::EdgeType;
9use petgraph::Undirected;
10use std::collections::{HashMap, HashSet};
11use std::fmt::Debug;
12use std::hash::Hash;
13
14pub struct NamedGraph<NodeName, NodeData, EdgeData, Ty = Undirected>
25where
26 NodeName: Clone + Hash + Eq + Send + Sync + Debug,
27 Ty: EdgeType,
28{
29 graph: StableGraph<NodeData, EdgeData, Ty>,
31
32 node_name_to_index: HashMap<NodeName, NodeIndex>,
34
35 index_to_node_name: HashMap<NodeIndex, NodeName>,
37}
38
39impl<NodeName, NodeData, EdgeData, Ty> NamedGraph<NodeName, NodeData, EdgeData, Ty>
40where
41 NodeName: Clone + Hash + Eq + Send + Sync + Debug,
42 Ty: EdgeType,
43{
44 pub fn new() -> Self {
46 Self {
47 graph: StableGraph::with_capacity(0, 0),
48 node_name_to_index: HashMap::new(),
49 index_to_node_name: HashMap::new(),
50 }
51 }
52
53 pub fn with_capacity(nodes: usize, edges: usize) -> Self {
55 Self {
56 graph: StableGraph::with_capacity(nodes, edges),
57 node_name_to_index: HashMap::with_capacity(nodes),
58 index_to_node_name: HashMap::with_capacity(nodes),
59 }
60 }
61
62 pub fn add_node(&mut self, node_name: NodeName, data: NodeData) -> Result<NodeIndex, String> {
66 if self.node_name_to_index.contains_key(&node_name) {
67 return Err(format!("Node already exists: {:?}", node_name));
68 }
69 let node = self.graph.add_node(data);
70 self.node_name_to_index.insert(node_name.clone(), node);
71 self.index_to_node_name.insert(node, node_name);
72 Ok(node)
73 }
74
75 pub fn has_node(&self, node_name: &NodeName) -> bool {
77 self.node_name_to_index.contains_key(node_name)
78 }
79
80 pub fn node_index(&self, node_name: &NodeName) -> Option<NodeIndex> {
82 self.node_name_to_index.get(node_name).copied()
83 }
84
85 pub fn node_name(&self, node: NodeIndex) -> Option<&NodeName> {
87 self.index_to_node_name.get(&node)
88 }
89
90 pub fn rename_node(&mut self, old_name: &NodeName, new_name: NodeName) -> Result<(), String> {
94 if old_name == &new_name {
95 return Ok(());
96 }
97 if self.node_name_to_index.contains_key(&new_name) {
98 return Err(format!("Node already exists: {:?}", new_name));
99 }
100
101 let node_idx = self
102 .node_name_to_index
103 .remove(old_name)
104 .ok_or_else(|| format!("Node not found: {:?}", old_name))?;
105
106 self.node_name_to_index.insert(new_name.clone(), node_idx);
107 self.index_to_node_name.insert(node_idx, new_name);
108 Ok(())
109 }
110
111 pub fn node_data(&self, node_name: &NodeName) -> Option<&NodeData> {
113 self.node_name_to_index
114 .get(node_name)
115 .and_then(|node| self.graph.node_weight(*node))
116 }
117
118 pub fn node_data_mut(&mut self, node_name: &NodeName) -> Option<&mut NodeData> {
120 self.node_name_to_index
121 .get(node_name)
122 .and_then(|node| self.graph.node_weight_mut(*node))
123 }
124
125 pub fn node_weight(&self, node: NodeIndex) -> Option<&NodeData> {
127 self.graph.node_weight(node)
128 }
129
130 pub fn node_weight_mut(&mut self, node: NodeIndex) -> Option<&mut NodeData> {
132 self.graph.node_weight_mut(node)
133 }
134
135 pub fn add_edge(
139 &mut self,
140 n1: &NodeName,
141 n2: &NodeName,
142 weight: EdgeData,
143 ) -> Result<EdgeIndex, String>
144 where
145 EdgeData: Clone,
146 {
147 let node1 = self
148 .node_name_to_index
149 .get(n1)
150 .ok_or_else(|| format!("Node not found: {:?}", n1))?;
151 let node2 = self
152 .node_name_to_index
153 .get(n2)
154 .ok_or_else(|| format!("Node not found: {:?}", n2))?;
155 Ok(self.graph.add_edge(*node1, *node2, weight))
156 }
157
158 pub fn edge_weight(&self, n1: &NodeName, n2: &NodeName) -> Option<&EdgeData> {
160 let node1 = self.node_name_to_index.get(n1)?;
161 let node2 = self.node_name_to_index.get(n2)?;
162 self.graph
163 .find_edge(*node1, *node2)
164 .and_then(|edge| self.graph.edge_weight(edge))
165 }
166
167 pub fn edge_weight_mut(&mut self, n1: &NodeName, n2: &NodeName) -> Option<&mut EdgeData> {
169 let node1 = self.node_name_to_index.get(n1)?;
170 let node2 = self.node_name_to_index.get(n2)?;
171 self.graph
172 .find_edge(*node1, *node2)
173 .and_then(|edge| self.graph.edge_weight_mut(edge))
174 }
175
176 pub fn neighbors(&self, node_name: &NodeName) -> Vec<&NodeName> {
178 self.node_name_to_index
179 .get(node_name)
180 .map(|node| {
181 self.graph
182 .neighbors(*node)
183 .filter_map(|n| self.index_to_node_name.get(&n))
184 .collect()
185 })
186 .unwrap_or_default()
187 }
188
189 pub fn node_names(&self) -> Vec<&NodeName> {
191 self.node_name_to_index.keys().collect()
192 }
193
194 pub fn node_count(&self) -> usize {
196 self.node_name_to_index.len()
197 }
198
199 pub fn edge_count(&self) -> usize {
201 self.graph.edge_count()
202 }
203
204 pub fn remove_node(&mut self, node_name: &NodeName) -> Option<NodeData> {
208 let node = self.node_name_to_index.remove(node_name)?;
209 self.index_to_node_name.remove(&node);
210 self.graph.remove_node(node)
211 }
212
213 pub fn remove_edge(&mut self, n1: &NodeName, n2: &NodeName) -> Option<EdgeData> {
217 let node1 = self.node_name_to_index.get(n1)?;
218 let node2 = self.node_name_to_index.get(n2)?;
219 self.graph
220 .find_edge(*node1, *node2)
221 .and_then(|edge| self.graph.remove_edge(edge))
222 }
223
224 pub fn contains_node(&self, node: NodeIndex) -> bool {
226 self.graph.contains_node(node)
227 }
228
229 pub fn graph(&self) -> &StableGraph<NodeData, EdgeData, Ty> {
233 &self.graph
234 }
235
236 pub fn graph_mut(&mut self) -> &mut StableGraph<NodeData, EdgeData, Ty> {
241 &mut self.graph
242 }
243
244 pub fn euler_tour_edges(&self, root: &NodeName) -> Option<Vec<(NodeIndex, NodeIndex)>> {
270 let root_idx = self.node_index(root)?;
271 Some(self.euler_tour_edges_by_index(root_idx))
272 }
273
274 pub fn euler_tour_edges_by_index(&self, root: NodeIndex) -> Vec<(NodeIndex, NodeIndex)> {
278 let mut visited_edges: HashSet<(NodeIndex, NodeIndex)> = HashSet::new();
279 let mut tour = Vec::new();
280 let mut stack = vec![root];
281
282 while let Some(u) = stack.last().copied() {
283 let mut pushed = false;
284
285 for v in self.graph.neighbors(u) {
287 if !visited_edges.contains(&(u, v)) {
288 visited_edges.insert((u, v));
290 visited_edges.insert((v, u));
291 tour.push((u, v));
293 stack.push(v);
295 pushed = true;
296 break; }
298 }
299
300 if !pushed {
301 stack.pop();
303 if let Some(&parent) = stack.last() {
304 tour.push((u, parent));
306 }
307 }
308 }
309
310 tour
311 }
312
313 pub fn euler_tour_vertices(&self, root: &NodeName) -> Option<Vec<NodeIndex>> {
326 let root_idx = self.node_index(root)?;
327 Some(self.euler_tour_vertices_by_index(root_idx))
328 }
329
330 pub fn euler_tour_vertices_by_index(&self, root: NodeIndex) -> Vec<NodeIndex> {
334 let edges = self.euler_tour_edges_by_index(root);
335 if edges.is_empty() {
336 return vec![root];
338 }
339 let mut vertices = vec![edges[0].0];
341 for (_, to) in &edges {
342 vertices.push(*to);
343 }
344 vertices
345 }
346}
347
348impl<NodeName, NodeData, EdgeData, Ty> Default for NamedGraph<NodeName, NodeData, EdgeData, Ty>
349where
350 NodeName: Clone + Hash + Eq + Send + Sync + Debug,
351 Ty: EdgeType,
352{
353 fn default() -> Self {
354 Self::new()
355 }
356}
357
358impl<NodeName, NodeData, EdgeData, Ty> Clone for NamedGraph<NodeName, NodeData, EdgeData, Ty>
359where
360 NodeName: Clone + Hash + Eq + Send + Sync + Debug,
361 NodeData: Clone,
362 EdgeData: Clone,
363 Ty: EdgeType,
364{
365 fn clone(&self) -> Self {
366 Self {
367 graph: self.graph.clone(),
368 node_name_to_index: self.node_name_to_index.clone(),
369 index_to_node_name: self.index_to_node_name.clone(),
370 }
371 }
372}
373
374impl<NodeName, NodeData, EdgeData, Ty> Debug for NamedGraph<NodeName, NodeData, EdgeData, Ty>
375where
376 NodeName: Clone + Hash + Eq + Send + Sync + Debug,
377 NodeData: Debug,
378 EdgeData: Debug,
379 Ty: EdgeType,
380{
381 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
382 f.debug_struct("NamedGraph")
383 .field("graph", &self.graph)
384 .field("node_name_to_index", &self.node_name_to_index)
385 .field("index_to_node_name", &self.index_to_node_name)
386 .finish()
387 }
388}
389
390#[cfg(test)]
391mod tests;