1use std::{
2 collections::{HashMap, HashSet},
3 fmt::Debug,
4 hash::RandomState,
5 ops::{Deref, DerefMut},
6};
7
8use crate::{
9 graph::{
10 Graph, GraphMut,
11 edge::{Edge, EdgeMut},
12 node::{Node, NodeMut},
13 },
14 registry::Identifier,
15};
16
17#[derive(Default, Clone)]
18pub(crate) struct RawNode<EdgeId: Identifier> {
19 pub edges: HashSet<EdgeId>,
20}
21
22#[derive(Clone)]
23pub(crate) struct RawEdge<NodeId: Identifier> {
24 pub from: NodeId,
25 pub to: NodeId,
26}
27
28impl<NodeId: Identifier + Debug> Debug for RawEdge<NodeId> {
29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 f.debug_struct("RawEdge")
31 .field("from", &self.from)
32 .field("to", &self.to)
33 .finish()
34 }
35}
36
37pub struct NodeRef<'graph, NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData> {
38 pub id: NodeId,
39 graph: &'graph OwningGraph<NodeId, EdgeId, NodeData, EdgeData>,
40}
41
42impl<'graph, NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData>
43 NodeRef<'graph, NodeId, EdgeId, NodeData, EdgeData>
44{
45 fn inner(&self) -> &'graph RawNode<EdgeId> {
46 &self.graph.nodes[&self.id]
47 }
48
49 pub fn data(&self) -> &'graph NodeData {
50 &self.graph.node_data[&self.id]
51 }
52}
53
54impl<'graph, NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData> Node<'graph>
55 for NodeRef<'graph, NodeId, EdgeId, NodeData, EdgeData>
56{
57 type Graph = OwningGraph<NodeId, EdgeId, NodeData, EdgeData>;
58
59 fn new(id: NodeId, graph: &'graph Self::Graph) -> Self {
60 NodeRef { id, graph }
61 }
62
63 fn id(&self) -> NodeId {
64 self.id
65 }
66
67 fn graph(&self) -> &'graph Self::Graph {
68 self.graph
69 }
70
71 fn edge_ids(&self) -> &'graph HashSet<EdgeId, RandomState> {
72 &self.inner().edges
73 }
74
75 fn edge_count(&self) -> usize {
76 self.inner().edges.len()
77 }
78}
79
80impl<NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData> Deref
81 for NodeRef<'_, NodeId, EdgeId, NodeData, EdgeData>
82{
83 type Target = NodeData;
84
85 fn deref(&self) -> &Self::Target {
86 self.data()
87 }
88}
89
90pub struct NodeMutRef<'graph, NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData> {
91 pub id: NodeId,
92 graph: &'graph mut OwningGraph<NodeId, EdgeId, NodeData, EdgeData>,
93}
94
95impl<'graph, NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData>
96 NodeMutRef<'graph, NodeId, EdgeId, NodeData, EdgeData>
97{
98 pub fn data(&mut self) -> &mut NodeData {
99 self.graph.node_data.get_mut(&self.id).unwrap()
100 }
101}
102
103impl<'graph, NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData> NodeMut<'graph>
104 for NodeMutRef<'graph, NodeId, EdgeId, NodeData, EdgeData>
105{
106 type Graph = OwningGraph<NodeId, EdgeId, NodeData, EdgeData>;
107
108 fn new(id: NodeId, graph: &'graph mut Self::Graph) -> Self {
109 NodeMutRef { id, graph }
110 }
111
112 fn id(&self) -> NodeId {
113 self.id
114 }
115
116 fn graph(&mut self) -> &mut Self::Graph {
117 self.graph
118 }
119
120 fn edge_ids(&self) -> &HashSet<EdgeId, RandomState> {
121 &self.graph.nodes.get(&self.id).unwrap().edges
122 }
123
124 fn edge_count(&self) -> usize {
125 self.graph.nodes.get(&self.id).unwrap().edges.len()
126 }
127
128 fn add_edge_id(&mut self, edge: EdgeId) {
129 self.graph
130 .nodes
131 .get_mut(&self.id)
132 .unwrap()
133 .edges
134 .insert(edge);
135 }
136
137 fn remove_edge_id(&mut self, edge: EdgeId) {
138 self.graph
139 .nodes
140 .get_mut(&self.id)
141 .unwrap()
142 .edges
143 .remove(&edge);
144 }
145}
146
147impl<NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData> Deref
148 for NodeMutRef<'_, NodeId, EdgeId, NodeData, EdgeData>
149{
150 type Target = NodeData;
151
152 fn deref(&self) -> &Self::Target {
153 self.graph.node_data.get(&self.id).unwrap()
154 }
155}
156
157impl<NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData> DerefMut
158 for NodeMutRef<'_, NodeId, EdgeId, NodeData, EdgeData>
159{
160 fn deref_mut(&mut self) -> &mut Self::Target {
161 self.graph.node_data.get_mut(&self.id).unwrap()
162 }
163}
164
165pub struct EdgeRef<'graph, NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData> {
166 pub id: EdgeId,
167 graph: &'graph OwningGraph<NodeId, EdgeId, NodeData, EdgeData>,
168}
169
170impl<'graph, EdgeId: Identifier + Debug, NodeId: Identifier + Debug, NodeData, EdgeData> Debug
171 for EdgeRef<'graph, NodeId, EdgeId, NodeData, EdgeData>
172{
173 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
174 f.debug_struct("Edge")
175 .field("id", &self.id)
176 .field("raw", self.inner())
177 .finish()
178 }
179}
180
181impl<'graph, NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData>
182 EdgeRef<'graph, NodeId, EdgeId, NodeData, EdgeData>
183{
184 fn inner(&self) -> &RawEdge<NodeId> {
185 &self.graph.edges[&self.id]
186 }
187
188 pub fn data(&self) -> &EdgeData {
189 &self.graph.edge_data[&self.id]
190 }
191}
192
193impl<'graph, NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData> Edge<'graph>
194 for EdgeRef<'graph, NodeId, EdgeId, NodeData, EdgeData>
195{
196 type Graph = OwningGraph<NodeId, EdgeId, NodeData, EdgeData>;
197
198 fn new(id: EdgeId, graph: &'graph Self::Graph) -> Self {
199 EdgeRef { id, graph }
200 }
201
202 fn id(&self) -> EdgeId {
203 self.id
204 }
205
206 fn graph(&self) -> &'graph Self::Graph {
207 self.graph
208 }
209
210 fn from_id(&self) -> NodeId {
211 self.inner().from
212 }
213
214 fn to_id(&self) -> NodeId {
215 self.inner().to
216 }
217}
218
219impl<'graph, NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData> Deref
220 for EdgeRef<'graph, NodeId, EdgeId, NodeData, EdgeData>
221{
222 type Target = EdgeData;
223
224 fn deref(&self) -> &Self::Target {
225 self.data()
226 }
227}
228
229pub struct EdgeMutRef<'graph, NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData> {
230 pub id: EdgeId,
231 graph: &'graph mut OwningGraph<NodeId, EdgeId, NodeData, EdgeData>,
232}
233
234impl<NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData>
235 EdgeMutRef<'_, NodeId, EdgeId, NodeData, EdgeData>
236{
237 pub fn data(&mut self) -> &mut EdgeData {
238 self.graph.edge_data.get_mut(&self.id).unwrap()
239 }
240}
241
242impl<'graph, NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData> EdgeMut<'graph>
243 for EdgeMutRef<'graph, NodeId, EdgeId, NodeData, EdgeData>
244{
245 type Graph = OwningGraph<NodeId, EdgeId, NodeData, EdgeData>;
246
247 fn new(id: <Self::Graph as Graph>::EdgeId, graph: &'graph mut Self::Graph) -> Self {
248 EdgeMutRef { id, graph }
249 }
250
251 fn id(&self) -> <Self::Graph as Graph>::EdgeId {
252 self.id
253 }
254
255 fn graph(&mut self) -> &mut Self::Graph {
256 self.graph
257 }
258
259 fn from_id(&self) -> <Self::Graph as Graph>::NodeId {
260 self.graph.get_edge(self.id).unwrap().from_id()
261 }
262
263 fn to_id(&self) -> <Self::Graph as Graph>::NodeId {
264 self.graph.get_edge(self.id).unwrap().to_id()
265 }
266
267 fn set_from(&mut self, node: <Self::Graph as Graph>::NodeId) {
268 self.graph.edges.get_mut(&self.id).unwrap().from = node;
269 }
270}
271
272impl<NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData> Deref
273 for EdgeMutRef<'_, NodeId, EdgeId, NodeData, EdgeData>
274{
275 type Target = EdgeData;
276
277 fn deref(&self) -> &Self::Target {
278 &self.graph.edge_data[&self.id]
279 }
280}
281
282impl<NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData> DerefMut
283 for EdgeMutRef<'_, NodeId, EdgeId, NodeData, EdgeData>
284{
285 fn deref_mut(&mut self) -> &mut Self::Target {
286 self.graph.edge_data.get_mut(&self.id).unwrap()
287 }
288}
289
290pub struct OwningGraph<NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData> {
292 node_data: HashMap<NodeId, NodeData>,
293 edge_data: HashMap<EdgeId, EdgeData>,
294
295 nodes: HashMap<NodeId, RawNode<EdgeId>>,
296 edges: HashMap<EdgeId, RawEdge<NodeId>>,
297
298 next_node_id: usize,
299 next_edge_id: usize,
300}
301
302impl<NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData> Default
303 for OwningGraph<NodeId, EdgeId, NodeData, EdgeData>
304{
305 fn default() -> Self {
306 Self {
307 node_data: HashMap::new(),
308 edge_data: HashMap::new(),
309 nodes: HashMap::new(),
310 edges: HashMap::new(),
311 next_node_id: 0,
312 next_edge_id: 0,
313 }
314 }
315}
316
317impl<NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData> Graph
318 for OwningGraph<NodeId, EdgeId, NodeData, EdgeData>
319{
320 type NodeId = NodeId;
321 type EdgeId = EdgeId;
322
323 type Hasher = RandomState;
327
328 type Node<'a>
329 = NodeRef<'a, NodeId, EdgeId, NodeData, EdgeData>
330 where
331 Self: 'a;
332
333 type Edge<'a>
334 = EdgeRef<'a, NodeId, EdgeId, NodeData, EdgeData>
335 where
336 Self: 'a;
337
338 fn get_node(&self, id: Self::NodeId) -> Option<Self::Node<'_>> {
339 if self.node_data.contains_key(&id) {
340 Some(NodeRef { id, graph: self })
341 } else {
342 None
343 }
344 }
345
346 fn get_edge(&self, id: Self::EdgeId) -> Option<Self::Edge<'_>> {
347 if self.edge_data.contains_key(&id) {
348 Some(EdgeRef { id, graph: self })
349 } else {
350 None
351 }
352 }
353
354 fn nodes(&self) -> impl Iterator<Item = Self::Node<'_>> + '_ {
355 self.node_data.keys().map(|id| self.get_node(*id).unwrap())
356 }
357
358 fn edges(&self) -> impl Iterator<Item = Self::Edge<'_>> + '_ {
359 self.edge_data.keys().map(|id| self.get_edge(*id).unwrap())
360 }
361}
362
363impl<NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData> GraphMut
364 for OwningGraph<NodeId, EdgeId, NodeData, EdgeData>
365{
366 type NodeMut<'a>
367 = NodeMutRef<'a, NodeId, EdgeId, NodeData, EdgeData>
368 where
369 Self: 'a;
370
371 type EdgeMut<'a>
372 = EdgeMutRef<'a, NodeId, EdgeId, NodeData, EdgeData>
373 where
374 Self: 'a;
375
376 fn get_node_mut(&mut self, id: Self::NodeId) -> Option<Self::NodeMut<'_>> {
377 if self.node_data.contains_key(&id) {
378 Some(NodeMutRef { id, graph: self })
379 } else {
380 None
381 }
382 }
383
384 fn get_edge_mut(&mut self, id: Self::EdgeId) -> Option<Self::EdgeMut<'_>> {
385 if self.edge_data.contains_key(&id) {
386 Some(EdgeMutRef { id, graph: self })
387 } else {
388 None
389 }
390 }
391}
392
393impl<NodeId: Identifier, EdgeId: Identifier, NodeData, EdgeData>
394 OwningGraph<NodeId, EdgeId, NodeData, EdgeData>
395{
396 pub fn make_node(&mut self, data: NodeData) -> NodeId {
399 let id = NodeId::from(self.next_node_id);
400 self.next_node_id += 1;
401 self.nodes.insert(
402 id,
403 RawNode {
404 edges: HashSet::new(),
405 },
406 );
407 self.node_data.insert(id, data);
408 id
409 }
410
411 pub fn make_edge(&mut self, from: NodeId, to: NodeId, data: EdgeData) -> EdgeId {
416 let id = EdgeId::from(self.next_edge_id);
417 self.next_edge_id += 1;
418 self.edges.insert(id, RawEdge { from, to });
419 self.edge_data.insert(id, data);
420 self.nodes.get_mut(&from).unwrap().edges.insert(id);
421 self.nodes.get_mut(&to).unwrap().edges.insert(id);
422 id
423 }
424
425 pub fn remove_edge(&mut self, id: EdgeId) {
430 let edge = self.edges.remove(&id).unwrap();
431 self.edge_data.remove(&id);
432
433 self.nodes.get_mut(&edge.from).unwrap().edges.remove(&id);
434
435 self.nodes.get_mut(&edge.to).unwrap().edges.remove(&id);
436 }
437
438 pub fn edit_edge(&mut self, id: EdgeId, new_from: NodeId, new_to: NodeId) {
440 let edge = self.edges.get_mut(&id).unwrap();
441
442 self.nodes.get_mut(&edge.from).unwrap().edges.remove(&id);
444 self.nodes.get_mut(&edge.to).unwrap().edges.remove(&id);
445
446 edge.from = new_from;
448 edge.to = new_to;
449
450 self.nodes.get_mut(&new_from).unwrap().edges.insert(id);
452 self.nodes.get_mut(&new_to).unwrap().edges.insert(id);
453 }
454
455 pub fn remove_node(&mut self, id: NodeId) {
460 let edges: Vec<EdgeId> = self.nodes[&id].edges.iter().copied().collect();
463 for edge_id in edges {
464 self.remove_edge(edge_id);
465 }
466 self.nodes.remove(&id).unwrap();
467 self.node_data.remove(&id);
468 }
469
470 pub fn reinterpret<NewNodeData, NewEdgeData, Fn, Fe>(
473 &self,
474 mut node_data_map: Fn,
475 mut edge_data_map: Fe,
476 ) -> OwningGraph<NodeId, EdgeId, NewNodeData, NewEdgeData>
477 where
478 Fn: FnMut(&NodeData) -> NewNodeData,
479 Fe: FnMut(&EdgeData) -> NewEdgeData,
480 {
481 OwningGraph {
482 node_data: self
483 .node_data
484 .iter()
485 .map(|(id, data)| (*id, node_data_map(data)))
486 .collect(),
487 edge_data: self
488 .edge_data
489 .iter()
490 .map(|(id, data)| (*id, edge_data_map(data)))
491 .collect(),
492 nodes: self.nodes.clone(),
493 edges: self.edges.clone(),
494 next_node_id: self.next_node_id,
495 next_edge_id: self.next_edge_id,
496 }
497 }
498}
499
500#[cfg(test)]
501mod tests {
502 use std::collections::HashSet;
503
504 use crate::{
505 graph::{
506 Graph, GraphMut,
507 edge::{Edge, EdgeMut},
508 node::{Node, NodeMut},
509 owning::OwningGraph,
510 },
511 registry::Identifier,
512 };
513
514 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
515 struct TestNodeId(usize);
516
517 impl From<usize> for TestNodeId {
518 fn from(value: usize) -> Self {
519 Self(value)
520 }
521 }
522
523 impl From<TestNodeId> for usize {
524 fn from(value: TestNodeId) -> Self {
525 value.0
526 }
527 }
528
529 impl Identifier for TestNodeId {}
530
531 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
532 struct TestEdgeId(usize);
533
534 impl From<usize> for TestEdgeId {
535 fn from(value: usize) -> Self {
536 Self(value)
537 }
538 }
539
540 impl From<TestEdgeId> for usize {
541 fn from(value: TestEdgeId) -> Self {
542 value.0
543 }
544 }
545
546 impl Identifier for TestEdgeId {}
547
548 type TestGraph = OwningGraph<TestNodeId, TestEdgeId, &'static str, i32>;
549
550 #[test]
551 fn editor_creates_nodes_edges_and_root() {
552 let mut graph = TestGraph::default();
553
554 let (root_id, child_id, edge_id) = {
555 let root_id = graph.make_node("root");
556 let child_id = graph.make_node("child");
557 let edge_id = graph.make_edge(root_id, child_id, 7);
558 (root_id, child_id, edge_id)
559 };
560
561 let root = graph.get_node(root_id).unwrap();
562 assert_eq!(root.id(), root_id);
563 assert_eq!(*root.data(), "root");
564
565 let child = graph.get_node(child_id).unwrap();
566 assert_eq!(*child.data(), "child");
567 assert!(child.parents().any(|item| item.node_id() == root_id));
568
569 let edge = graph.get_edge(edge_id).unwrap();
570 assert_eq!(edge.id(), edge_id);
571 assert_eq!(edge.from().id(), root_id);
572 assert_eq!(edge.to().id(), child_id);
573 assert_eq!(*edge.data(), 7);
574 assert!(!edge.is_loop());
575 }
576
577 #[test]
578 fn node_and_edge_iterators_cover_all_items() {
579 let mut graph = TestGraph::default();
580
581 {
582 let a = graph.make_node("a");
583 let b = graph.make_node("b");
584 let c = graph.make_node("c");
585 graph.make_edge(a, b, 1);
586 graph.make_edge(b, c, 2);
587 }
588
589 let node_values: HashSet<_> = graph.nodes().map(|node| *node.data()).collect();
590 let edge_values: HashSet<_> = graph.edges().map(|edge| *edge.data()).collect();
591
592 assert_eq!(node_values, HashSet::from(["a", "b", "c"]));
593 assert_eq!(edge_values, HashSet::from([1, 2]));
594 }
595
596 #[test]
597 fn mutable_handles_can_update_payloads() {
598 let mut graph = TestGraph::default();
599
600 let (node_id, edge_id) = {
601 let n0 = graph.make_node("initial");
602 let n1 = graph.make_node("other");
603 let e0 = graph.make_edge(n0, n1, 10);
604 (n0, e0)
605 };
606
607 *graph.get_node_mut(node_id).unwrap().data() = "updated";
608 *graph.get_edge_mut(edge_id).unwrap().data() = 99;
609
610 assert_eq!(*graph.get_node(node_id).unwrap().data(), "updated");
611 assert_eq!(*graph.get_edge(edge_id).unwrap().data(), 99);
612 }
613
614 #[test]
615 fn remove_edge_updates_connected_nodes() {
616 let mut graph = TestGraph::default();
617
618 let (a, b, edge_id) = {
619 let a = graph.make_node("a");
620 let b = graph.make_node("b");
621 let edge_id = graph.make_edge(a, b, 3);
622 (a, b, edge_id)
623 };
624
625 assert_eq!(graph.get_node(a).unwrap().edge_count(), 1);
626 assert_eq!(graph.get_node(b).unwrap().edge_count(), 1);
627
628 graph.remove_edge(edge_id);
629
630 assert_eq!(graph.get_node(a).unwrap().edge_count(), 0);
631 assert_eq!(graph.get_node(b).unwrap().edge_count(), 0);
632 assert_eq!(graph.edges().count(), 0);
633 }
634
635 #[test]
636 fn make_edge_does_not_overwrite_existing_after_remove() {
637 let mut graph = TestGraph::default();
638
639 let (a, b, c, d) = {
640 let a = graph.make_node("a");
641 let b = graph.make_node("b");
642 let c = graph.make_node("c");
643 let d = graph.make_node("d");
644 (a, b, c, d)
645 };
646
647 let e0 = graph.make_edge(a, b, 10);
648 let _e1 = graph.make_edge(b, c, 20);
649
650 graph.remove_edge(e0);
651
652 let _e2 = graph.make_edge(c, d, 30);
653
654 let edge_values: HashSet<_> = graph.edges().map(|edge| *edge.data()).collect();
655 assert_eq!(edge_values, HashSet::from([20, 30]));
656 assert_eq!(graph.edges().count(), 2);
657 }
658
659 #[test]
660 fn merge_nodes_rehomes_outgoing_edges_to_keep() {
661 let mut graph = TestGraph::default();
665
666 let (a, b, c) = {
667 let a = graph.make_node("a");
668 let b = graph.make_node("b");
669 let c = graph.make_node("c");
670 (a, b, c)
671 };
672 let e0 = graph.make_edge(a, b, 1);
673 let e1 = graph.make_edge(b, c, 2);
674
675 graph.merge_nodes(a, b, e0);
676
677 assert!(!graph.get_node(a).unwrap().edge_ids().contains(&e0));
679 assert!(!graph.get_node(b).unwrap().edge_ids().contains(&e0));
680
681 assert_eq!(graph.get_edge(e1).unwrap().from_id(), a);
683 assert!(graph.get_node(a).unwrap().edge_ids().contains(&e1));
684 assert!(!graph.get_node(b).unwrap().edge_ids().contains(&e1));
685
686 assert_eq!(graph.get_node(b).unwrap().edge_count(), 0);
688
689 let a_children: Vec<_> = graph.get_node(a).unwrap().children().collect();
691 assert_eq!(a_children.len(), 1);
692 assert_eq!(a_children[0].node_id(), c);
693 assert_eq!(a_children[0].edge_id(), e1);
694 }
695
696 #[test]
697 fn merge_nodes_handles_multiple_outgoing_edges_on_removed_node() {
698 let mut graph = TestGraph::default();
702
703 let (a, b, c, d) = {
704 let a = graph.make_node("a");
705 let b = graph.make_node("b");
706 let c = graph.make_node("c");
707 let d = graph.make_node("d");
708 (a, b, c, d)
709 };
710 let e0 = graph.make_edge(a, b, 10);
711 let e1 = graph.make_edge(b, c, 20);
712 let e2 = graph.make_edge(b, d, 30);
713
714 graph.merge_nodes(a, b, e0);
715
716 assert_eq!(graph.get_node(b).unwrap().edge_count(), 0);
717
718 let a_successors: HashSet<_> = graph
719 .get_node(a)
720 .unwrap()
721 .children()
722 .map(|item| item.node_id())
723 .collect();
724 assert_eq!(a_successors, HashSet::from([c, d]));
725
726 assert_eq!(graph.get_edge(e1).unwrap().from_id(), a);
727 assert_eq!(graph.get_edge(e2).unwrap().from_id(), a);
728 }
729
730 #[test]
731 fn merge_nodes_on_tail_node_leaves_keep_with_no_outgoing_edges() {
732 let mut graph = TestGraph::default();
736
737 let (a, b) = {
738 let a = graph.make_node("a");
739 let b = graph.make_node("b");
740 (a, b)
741 };
742 let e0 = graph.make_edge(a, b, 1);
743
744 graph.merge_nodes(a, b, e0);
745
746 assert_eq!(graph.get_node(a).unwrap().children().count(), 0);
747 assert_eq!(graph.get_node(b).unwrap().edge_count(), 0);
748 }
749
750 #[test]
751 fn merge_nodes_does_not_touch_incoming_edges_of_keep() {
752 let mut graph = TestGraph::default();
756
757 let (p, a, b, c) = {
758 let p = graph.make_node("p");
759 let a = graph.make_node("a");
760 let b = graph.make_node("b");
761 let c = graph.make_node("c");
762 (p, a, b, c)
763 };
764 let ep = graph.make_edge(p, a, 0);
765 let e0 = graph.make_edge(a, b, 1);
766 graph.make_edge(b, c, 2);
767
768 graph.merge_nodes(a, b, e0);
769
770 assert_eq!(graph.get_edge(ep).unwrap().from_id(), p);
772 assert_eq!(graph.get_edge(ep).unwrap().to_id(), a);
773 assert!(graph.get_node(a).unwrap().edge_ids().contains(&ep));
774
775 assert_eq!(graph.get_node(a).unwrap().edge_count(), 2);
777 }
778
779 #[test]
780 fn directed_dfs_visits_reachable_nodes() {
781 let mut graph = TestGraph::default();
782
783 let (root, b, c, isolated) = {
784 let root = graph.make_node("root");
785 let b = graph.make_node("b");
786 let c = graph.make_node("c");
787 let isolated = graph.make_node("isolated");
788
789 graph.make_edge(root, b, 1);
790 graph.make_edge(b, c, 2);
791
792 (root, b, c, isolated)
793 };
794
795 let mut seen = HashSet::new();
796 let mut root_count = 0;
797
798 for (edge, node) in graph.dfs(root) {
799 if node.id() == root {
800 root_count += 1;
801 assert!(edge.is_none());
802 }
803 seen.insert(node.id());
804 }
805
806 assert_eq!(root_count, 1);
807 assert!(seen.contains(&root));
808 assert!(seen.contains(&b));
809 assert!(seen.contains(&c));
810 assert!(!seen.contains(&isolated));
811 }
812
813 #[test]
814 fn undirected_dfs_can_reach_incoming_neighbors() {
815 let mut graph = TestGraph::default();
816
817 let (root, parent) = {
818 let root = graph.make_node("root");
819 let parent = graph.make_node("parent");
820
821 graph.make_edge(parent, root, 5);
822
823 (root, parent)
824 };
825
826 let directed_seen: HashSet<_> = graph.dfs(root).map(|(_, node)| node.id()).collect();
827
828 let undirected_seen: HashSet<_> = graph
829 .undirected_dfs(root)
830 .map(|(_, node)| node.id())
831 .collect();
832
833 assert!(directed_seen.contains(&root));
834 assert!(!directed_seen.contains(&parent));
835 assert!(undirected_seen.contains(&root));
836 assert!(undirected_seen.contains(&parent));
837 }
838
839 #[test]
840 fn trait_views_traverse_and_mutate_edges_without_losing_connectivity() {
841 let mut graph = TestGraph::default();
842 let a = graph.make_node("a");
843 let b = graph.make_node("b");
844 let loop_node = graph.make_node("loop");
845 let edge = graph.make_edge(a, b, 1);
846 let loop_edge = graph.make_edge(loop_node, loop_node, 2);
847
848 let a_ref = graph.get_node(a).unwrap();
849 assert!(!a_ref.is_leaf());
850 assert_eq!(a_ref.edges().count(), 1);
851 let step = a_ref.children().next().unwrap();
852 assert_eq!(step.edge().id(), edge);
853 assert_eq!(step.node().id(), b);
854 assert!(graph.get_edge(loop_edge).unwrap().is_loop());
855
856 {
857 let mut a_mut = graph.get_node_mut(a).unwrap();
858 assert_eq!(a_mut.edge_count(), 1);
859 a_mut.remove_edge_id(edge);
860 assert!(a_mut.as_ref().is_leaf());
861 a_mut.add_edge_id(edge);
862 assert_eq!(a_mut.as_ref().edge_count(), 1);
863 }
864
865 {
866 let mut edge_mut = graph.get_edge_mut(edge).unwrap();
867 assert_eq!(edge_mut.as_ref().to_id(), b);
868 assert_eq!(edge_mut.from().id(), a);
869 assert_eq!(edge_mut.to().id(), b);
870 *edge_mut.data() = 9;
871 edge_mut.set_from(a);
872 }
873 assert_eq!(*graph.get_edge(edge).unwrap().data(), 9);
874 }
875
876 #[test]
877 fn editing_reinterpreting_and_removing_nodes_preserves_graph_invariants() {
878 let mut graph = TestGraph::default();
879 let a = graph.make_node("a");
880 let b = graph.make_node("b");
881 let c = graph.make_node("c");
882 let edge = graph.make_edge(a, b, 4);
883
884 graph.edit_edge(edge, b, c);
885 let edited = graph.get_edge(edge).unwrap();
886 assert_eq!(edited.from_id(), b);
887 assert_eq!(edited.to_id(), c);
888 assert_eq!(graph.get_node(a).unwrap().edge_count(), 0);
889 assert_eq!(graph.get_node(b).unwrap().edge_count(), 1);
890 assert_eq!(graph.get_node(c).unwrap().edge_count(), 1);
891
892 let reinterpreted = graph.reinterpret(|node| node.len(), |edge| edge * 10);
893 assert_eq!(*reinterpreted.get_node(a).unwrap().data(), 1);
894 assert_eq!(*reinterpreted.get_edge(edge).unwrap().data(), 40);
895
896 graph.remove_node(b);
897 assert!(graph.get_node(b).is_none());
898 assert!(graph.get_edge(edge).is_none());
899 assert_eq!(graph.get_node(c).unwrap().edge_count(), 0);
900 }
901}