rapier3d/data/graph.rs
1// This is basically a stripped down version of petgraph's UnGraph.
2// - It is not generic with respect to the index type (we always use u32).
3// - It preserves associated edge iteration order after Serialization/Deserialization.
4// - It is always undirected.
5//! A stripped-down version of petgraph's UnGraph.
6use crate::alloc_prelude::*;
7
8use core::cmp::max;
9use core::ops::{Index, IndexMut};
10
11/// Node identifier.
12#[derive(Copy, Clone, Default, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
13#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
14pub struct NodeIndex(u32);
15
16impl NodeIndex {
17 #[inline]
18 pub fn new(x: u32) -> Self {
19 NodeIndex(x)
20 }
21
22 #[inline]
23 pub fn index(self) -> usize {
24 self.0 as usize
25 }
26
27 #[inline]
28 pub fn end() -> Self {
29 NodeIndex(crate::INVALID_U32)
30 }
31
32 fn _into_edge(self) -> EdgeIndex {
33 EdgeIndex(self.0)
34 }
35}
36
37impl From<u32> for NodeIndex {
38 fn from(ix: u32) -> Self {
39 NodeIndex(ix)
40 }
41}
42
43/// Edge identifier.
44#[derive(Copy, Clone, Default, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
45#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
46pub struct EdgeIndex(u32);
47
48impl EdgeIndex {
49 #[inline]
50 pub fn new(x: u32) -> Self {
51 EdgeIndex(x)
52 }
53
54 #[inline]
55 pub fn index(self) -> usize {
56 self.0 as usize
57 }
58
59 /// An invalid `EdgeIndex` used to denote absence of an edge, for example
60 /// to end an adjacency list.
61 #[inline]
62 pub fn end() -> Self {
63 EdgeIndex(crate::INVALID_U32)
64 }
65
66 fn _into_node(self) -> NodeIndex {
67 NodeIndex(self.0)
68 }
69}
70
71impl From<u32> for EdgeIndex {
72 fn from(ix: u32) -> Self {
73 EdgeIndex(ix)
74 }
75}
76
77#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
78#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
79pub enum Direction {
80 Outgoing = 0,
81 Incoming = 1,
82}
83
84impl Direction {
85 fn opposite(self) -> Direction {
86 match self {
87 Direction::Outgoing => Direction::Incoming,
88 Direction::Incoming => Direction::Outgoing,
89 }
90 }
91}
92
93const DIRECTIONS: [Direction; 2] = [Direction::Outgoing, Direction::Incoming];
94
95/// The graph's node type.
96#[derive(Debug, Copy, Clone)]
97#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
98pub struct Node<N> {
99 /// Associated node data.
100 pub weight: N,
101 /// Next edge in outgoing and incoming edge lists.
102 next: [EdgeIndex; 2],
103}
104
105/// The graph's edge type.
106#[derive(Debug, Copy, Clone)]
107#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
108pub struct Edge<E> {
109 /// Associated edge data.
110 pub weight: E,
111 /// Next edge in outgoing and incoming edge lists.
112 next: [EdgeIndex; 2],
113 /// Previous edge in outgoing and incoming edge lists (`EdgeIndex::end()`
114 /// when this edge is the list head stored on the node). Kept so unlinking
115 /// an edge — the broad-phase's bread and butter on churn-heavy scenes — is
116 /// O(1) instead of an O(degree) list walk per endpoint.
117 prev: [EdgeIndex; 2],
118 /// Start and End node index
119 node: [NodeIndex; 2],
120}
121
122impl<E> Edge<E> {
123 /// Return the source node index.
124 pub fn source(&self) -> NodeIndex {
125 self.node[0]
126 }
127
128 /// Return the target node index.
129 pub fn target(&self) -> NodeIndex {
130 self.node[1]
131 }
132}
133
134#[derive(Clone, Debug, Default)]
135#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
136pub struct Graph<N, E> {
137 pub(crate) nodes: Vec<Node<N>>,
138 pub(crate) edges: Vec<Edge<E>>,
139}
140
141enum Pair<T> {
142 Both(T, T),
143 One(T),
144 None,
145}
146
147/// Get mutable references at index `a` and `b`.
148fn index_twice<T>(arr: &mut [T], a: usize, b: usize) -> Pair<&mut T> {
149 if max(a, b) >= arr.len() {
150 Pair::None
151 } else if a == b {
152 Pair::One(&mut arr[max(a, b)])
153 } else {
154 // Never fails: a, b are in bounds and distinct.
155 let [ar, br] = arr
156 .get_disjoint_mut([a, b])
157 .expect("indices are in bounds and distinct");
158 Pair::Both(ar, br)
159 }
160}
161
162impl<N, E> Graph<N, E> {
163 /// Create a new `Graph` with estimated capacity.
164 pub fn with_capacity(nodes: usize, edges: usize) -> Self {
165 Graph {
166 nodes: Vec::with_capacity(nodes),
167 edges: Vec::with_capacity(edges),
168 }
169 }
170
171 /// Add a node (also called vertex) with associated data `weight` to the graph.
172 ///
173 /// Computes in **O(1)** time.
174 ///
175 /// Return the index of the new node.
176 ///
177 /// **Panics** if the Graph is at the maximum number of nodes for its index
178 /// type (N/A if usize).
179 pub fn add_node(&mut self, weight: N) -> NodeIndex {
180 let node = Node {
181 weight,
182 next: [EdgeIndex::end(), EdgeIndex::end()],
183 };
184 assert!(self.nodes.len() != crate::INVALID_USIZE);
185 let node_idx = NodeIndex::new(self.nodes.len() as u32);
186 self.nodes.push(node);
187 node_idx
188 }
189
190 /// Access the weight for node `a`.
191 ///
192 /// Also available with indexing syntax: `&graph[a]`.
193 pub fn node_weight(&self, a: NodeIndex) -> Option<&N> {
194 self.nodes.get(a.index()).map(|n| &n.weight)
195 }
196
197 /// Access the weight for edge `a`.
198 ///
199 /// Also available with indexing syntax: `&graph[a]`.
200 pub fn edge_weight(&self, a: EdgeIndex) -> Option<&E> {
201 self.edges.get(a.index()).map(|e| &e.weight)
202 }
203
204 /// Access the weight for edge `a` mutably.
205 ///
206 /// Also available with indexing syntax: `&mut graph[a]`.
207 pub fn edge_weight_mut(&mut self, a: EdgeIndex) -> Option<&mut E> {
208 self.edges.get_mut(a.index()).map(|e| &mut e.weight)
209 }
210
211 /// Add an edge from `a` to `b` to the graph, with its associated
212 /// data `weight`.
213 ///
214 /// Return the index of the new edge.
215 ///
216 /// Computes in **O(1)** time.
217 ///
218 /// **Panics** if any of the nodes don't exist.<br>
219 /// **Panics** if the Graph is at the maximum number of edges for its index
220 /// type (N/A if usize).
221 ///
222 /// **Note:** `Graph` allows adding parallel (“duplicate”) edges. If you want
223 /// to avoid this, use [`.update_edge(a, b, weight)`](#method.update_edge) instead.
224 pub fn add_edge(&mut self, a: NodeIndex, b: NodeIndex, weight: E) -> EdgeIndex {
225 assert!(self.edges.len() != crate::INVALID_USIZE);
226 let edge_idx = EdgeIndex::new(self.edges.len() as u32);
227 let mut edge = Edge {
228 weight,
229 node: [a, b],
230 next: [EdgeIndex::end(); 2],
231 prev: [EdgeIndex::end(); 2],
232 };
233 match index_twice(&mut self.nodes, a.index(), b.index()) {
234 Pair::None => panic!("Graph::add_edge: node indices out of bounds"),
235 Pair::One(an) => {
236 edge.next = an.next;
237 an.next[0] = edge_idx;
238 an.next[1] = edge_idx;
239 }
240 Pair::Both(an, bn) => {
241 // a and b are different indices
242 edge.next = [an.next[0], bn.next[1]];
243 an.next[0] = edge_idx;
244 bn.next[1] = edge_idx;
245 }
246 }
247 // Back-links of the displaced list heads (doubly-linked adjacency).
248 for k in 0..2 {
249 let nxt = edge.next[k];
250 if nxt != EdgeIndex::end() {
251 self.edges[nxt.index()].prev[k] = edge_idx;
252 }
253 }
254 self.edges.push(edge);
255 edge_idx
256 }
257
258 /// Access the source and target nodes for `e`.
259 pub fn edge_endpoints(&self, e: EdgeIndex) -> Option<(NodeIndex, NodeIndex)> {
260 self.edges
261 .get(e.index())
262 .map(|ed| (ed.source(), ed.target()))
263 }
264
265 /// Remove `a` from the graph if it exists, and return its weight.
266 /// If it doesn't exist in the graph, return `None`.
267 ///
268 /// Apart from `a`, this invalidates the last node index in the graph
269 /// (that node will adopt the removed node index). Edge indices are
270 /// invalidated as they would be following the removal of each edge
271 /// with an endpoint in `a`.
272 ///
273 /// Computes in **O(e')** time, where **e'** is the number of affected
274 /// edges, including *n* calls to `.remove_edge()` where *n* is the number
275 /// of edges with an endpoint in `a`, and including the edges with an
276 /// endpoint in the displaced node.
277 pub fn remove_node(&mut self, a: NodeIndex) -> Option<N> {
278 self.remove_node_with(a, &mut |_| {})
279 }
280
281 /// Same as [`Self::remove_node`], invoking `on_remove` with each removed edge
282 /// index right before its removal is applied, so side arrays indexed like
283 /// `self.edges` can mirror the `swap_remove`s.
284 pub fn remove_node_with(
285 &mut self,
286 a: NodeIndex,
287 on_remove: &mut dyn FnMut(EdgeIndex),
288 ) -> Option<N> {
289 self.nodes.get(a.index())?;
290 for d in &DIRECTIONS {
291 let k = *d as usize;
292
293 // Remove all edges from and to this node.
294 loop {
295 let next = self.nodes[a.index()].next[k];
296 if next == EdgeIndex::end() {
297 break;
298 }
299 let ret = self.remove_edge_with(next, on_remove);
300 debug_assert!(ret.is_some());
301 let _ = ret;
302 }
303 }
304
305 // Use swap_remove -- only the swapped-in node is going to change
306 // NodeIndex, so we only have to walk its edges and update them.
307
308 let node = self.nodes.swap_remove(a.index());
309
310 // Find the edge lists of the node that had to relocate.
311 // It may be that no node had to relocate, then we are done already.
312 let swap_edges = match self.nodes.get(a.index()) {
313 None => return Some(node.weight),
314 Some(ed) => ed.next,
315 };
316
317 // The swapped element's old index
318 let old_index = NodeIndex::new(self.nodes.len() as u32);
319 let new_index = a;
320
321 // Adjust the starts of the out edges, and ends of the in edges.
322 for &d in &DIRECTIONS {
323 let k = d as usize;
324 let mut edges = edges_walker_mut(&mut self.edges, swap_edges[k], d);
325 while let Some(curedge) = edges.next_edge() {
326 debug_assert!(curedge.node[k] == old_index);
327 curedge.node[k] = new_index;
328 }
329 }
330 Some(node.weight)
331 }
332
333 /// Unlinks edge `e` from the adjacency lists of both its endpoints, in O(1)
334 /// through the doubly-linked `prev`/`next` edge links. `e`'s own links are
335 /// left untouched (it is about to be removed or rewritten by the caller).
336 fn unlink_edge(&mut self, e: EdgeIndex) {
337 let (edge_node, edge_next, edge_prev) = {
338 let ed = &self.edges[e.index()];
339 (ed.node, ed.next, ed.prev)
340 };
341 for &d in &DIRECTIONS {
342 let k = d as usize;
343 let prev = edge_prev[k];
344 let next = edge_next[k];
345 if prev == EdgeIndex::end() {
346 // `e` is the list head stored on the node.
347 if let Some(node) = self.nodes.get_mut(edge_node[k].index()) {
348 debug_assert!(node.next[k] == e);
349 node.next[k] = next;
350 } else {
351 debug_assert!(
352 false,
353 "Edge's endpoint dir={:?} index={:?} not found",
354 d, edge_node[k]
355 );
356 }
357 } else {
358 debug_assert!(self.edges[prev.index()].next[k] == e);
359 self.edges[prev.index()].next[k] = next;
360 }
361 if next != EdgeIndex::end() {
362 debug_assert!(self.edges[next.index()].prev[k] == e);
363 self.edges[next.index()].prev[k] = prev;
364 }
365 }
366 }
367
368 /// Rewrites the neighbors' (and head's) links pointing at edge `e` — whose
369 /// links are valid but whose index just changed — to `new_e`, in O(1)
370 /// through the doubly-linked edge links. The caller must already have moved
371 /// the edge's data to `new_e`'s slot.
372 fn relink_edge(&mut self, new_e: EdgeIndex) {
373 let (edge_node, edge_next, edge_prev) = {
374 let ed = &self.edges[new_e.index()];
375 (ed.node, ed.next, ed.prev)
376 };
377 for &d in &DIRECTIONS {
378 let k = d as usize;
379 let prev = edge_prev[k];
380 let next = edge_next[k];
381 if prev == EdgeIndex::end() {
382 if let Some(node) = self.nodes.get_mut(edge_node[k].index()) {
383 node.next[k] = new_e;
384 }
385 } else {
386 self.edges[prev.index()].next[k] = new_e;
387 }
388 if next != EdgeIndex::end() {
389 self.edges[next.index()].prev[k] = new_e;
390 }
391 }
392 }
393
394 /// Remove an edge and return its edge weight, or `None` if it didn't exist.
395 ///
396 /// Apart from `e`, this invalidates the last edge index in the graph
397 /// (that edge will adopt the removed edge index).
398 ///
399 /// Computes in **O(e')** time, where **e'** is the size of four particular edge lists, for
400 /// the vertices of `e` and the vertices of another affected edge.
401 pub fn remove_edge(&mut self, e: EdgeIndex) -> Option<E> {
402 self.remove_edge_with(e, &mut |_| {})
403 }
404
405 /// Same as [`Self::remove_edge`], invoking `on_remove` with the edge index right
406 /// before the removal is applied, so side arrays indexed like `self.edges` can
407 /// mirror the `swap_remove`.
408 pub fn remove_edge_with(
409 &mut self,
410 e: EdgeIndex,
411 on_remove: &mut dyn FnMut(EdgeIndex),
412 ) -> Option<E> {
413 // every edge is part of two lists,
414 // outgoing and incoming edges.
415 // Remove it from both
416 self.edges.get(e.index())?;
417 self.unlink_edge(e);
418 on_remove(e);
419 self.remove_edge_adjust_indices(e)
420 }
421
422 fn remove_edge_adjust_indices(&mut self, e: EdgeIndex) -> Option<E> {
423 // swap_remove the edge -- only the removed edge
424 // and the edge swapped into place are affected and need updating
425 // indices.
426 let edge = self.edges.swap_remove(e.index());
427 if e.index() < self.edges.len() {
428 // An edge was swapped into the removed slot: rewrite the links
429 // pointing at its old index (the last slot) to `e`.
430 self.relink_edge(e);
431 }
432 Some(edge.weight)
433 }
434
435 /// Return an iterator of all edges of `a`.
436 ///
437 /// - `Directed`: Outgoing edges from `a`.
438 /// - `Undirected`: All edges connected to `a`.
439 ///
440 /// Produces an empty iterator if the node doesn't exist.<br>
441 /// Iterator element type is `EdgeReference<E, Ix>`.
442 pub fn edges(&self, a: NodeIndex) -> Edges<'_, E> {
443 self.edges_directed(a, Direction::Outgoing)
444 }
445
446 /// Return an iterator of all edges of `a`, in the specified direction.
447 ///
448 /// - `Directed`, `Outgoing`: All edges from `a`.
449 /// - `Directed`, `Incoming`: All edges to `a`.
450 /// - `Undirected`, `Outgoing`: All edges connected to `a`, with `a` being the source of each
451 /// edge.
452 /// - `Undirected`, `Incoming`: All edges connected to `a`, with `a` being the target of each
453 /// edge.
454 ///
455 /// Produces an empty iterator if the node `a` doesn't exist.<br>
456 /// Iterator element type is `EdgeReference<E, Ix>`.
457 pub fn edges_directed(&self, a: NodeIndex, dir: Direction) -> Edges<'_, E> {
458 Edges {
459 skip_start: a,
460 edges: &self.edges,
461 direction: dir,
462 next: match self.nodes.get(a.index()) {
463 None => [EdgeIndex::end(), EdgeIndex::end()],
464 Some(n) => n.next,
465 },
466 }
467 }
468
469 /*
470 /// Return an iterator over all the edges connecting `a` and `b`.
471 ///
472 /// - `Directed`: Outgoing edges from `a`.
473 /// - `Undirected`: All edges connected to `a`.
474 ///
475 /// Iterator element type is `EdgeReference<E, Ix>`.
476 pub fn edges_connecting(&self, a: NodeIndex, b: NodeIndex) -> EdgesConnecting<E, Ty, Ix> {
477 EdgesConnecting {
478 target_node: b,
479 edges: self.edges_directed(a, Direction::Outgoing),
480 ty: PhantomData,
481 }
482 }
483 */
484
485 /// Lookup an edge from `a` to `b`.
486 ///
487 /// Computes in **O(e')** time, where **e'** is the number of edges
488 /// connected to `a` (and `b`, if the graph edges are undirected).
489 pub fn find_edge(&self, a: NodeIndex, b: NodeIndex) -> Option<EdgeIndex> {
490 self.find_edge_undirected(a, b).map(|(ix, _)| ix)
491 }
492
493 /// Return an iterator over all the edges connecting `a` and `b`, in either direction.
494 ///
495 /// Unlike [`Self::find_edge`], this yields every parallel edge between the two
496 /// nodes instead of only the first one found.
497 pub fn edges_between(
498 &self,
499 a: NodeIndex,
500 b: NodeIndex,
501 ) -> impl Iterator<Item = EdgeIndex> + '_ {
502 self.edges(a).filter_map(move |e| {
503 let node = self.edges[e.id().index()].node;
504 (node == [a, b] || node == [b, a]).then_some(e.id())
505 })
506 }
507
508 /// Lookup an edge between `a` and `b`, in either direction.
509 ///
510 /// If the graph is undirected, then this is equivalent to `.find_edge()`.
511 ///
512 /// Return the edge index and its directionality, with `Outgoing` meaning
513 /// from `a` to `b` and `Incoming` the reverse,
514 /// or `None` if the edge does not exist.
515 pub fn find_edge_undirected(
516 &self,
517 a: NodeIndex,
518 b: NodeIndex,
519 ) -> Option<(EdgeIndex, Direction)> {
520 match self.nodes.get(a.index()) {
521 None => None,
522 Some(node) => self.find_edge_undirected_from_node(node, b),
523 }
524 }
525
526 fn find_edge_undirected_from_node(
527 &self,
528 node: &Node<N>,
529 b: NodeIndex,
530 ) -> Option<(EdgeIndex, Direction)> {
531 for &d in &DIRECTIONS {
532 let k = d as usize;
533 let mut edix = node.next[k];
534 while let Some(edge) = self.edges.get(edix.index()) {
535 if edge.node[1 - k] == b {
536 return Some((edix, d));
537 }
538 edix = edge.next[k];
539 }
540 }
541 None
542 }
543
544 /// Access the internal node array.
545 pub fn raw_nodes(&self) -> &[Node<N>] {
546 &self.nodes
547 }
548
549 /// Access the internal edge array.
550 pub fn raw_edges(&self) -> &[Edge<E>] {
551 &self.edges
552 }
553
554 /// Accessor for data structure internals: the first edge in the given direction.
555 pub fn first_edge(&self, a: NodeIndex, dir: Direction) -> Option<EdgeIndex> {
556 match self.nodes.get(a.index()) {
557 None => None,
558 Some(node) => {
559 let edix = node.next[dir as usize];
560 if edix == EdgeIndex::end() {
561 None
562 } else {
563 Some(edix)
564 }
565 }
566 }
567 }
568
569 /// Accessor for data structure internals: the next edge for the given direction.
570 pub fn next_edge(&self, e: EdgeIndex, dir: Direction) -> Option<EdgeIndex> {
571 match self.edges.get(e.index()) {
572 None => None,
573 Some(node) => {
574 let edix = node.next[dir as usize];
575 if edix == EdgeIndex::end() {
576 None
577 } else {
578 Some(edix)
579 }
580 }
581 }
582 }
583}
584
585struct EdgesWalkerMut<'a, E: 'a> {
586 edges: &'a mut [Edge<E>],
587 next: EdgeIndex,
588 dir: Direction,
589}
590
591fn edges_walker_mut<E>(
592 edges: &mut [Edge<E>],
593 next: EdgeIndex,
594 dir: Direction,
595) -> EdgesWalkerMut<'_, E> {
596 EdgesWalkerMut { edges, next, dir }
597}
598
599impl<E> EdgesWalkerMut<'_, E> {
600 fn next_edge(&mut self) -> Option<&mut Edge<E>> {
601 self.next().map(|t| t.1)
602 }
603
604 fn next(&mut self) -> Option<(EdgeIndex, &mut Edge<E>)> {
605 let this_index = self.next;
606 let k = self.dir as usize;
607 match self.edges.get_mut(self.next.index()) {
608 None => None,
609 Some(edge) => {
610 self.next = edge.next[k];
611 Some((this_index, edge))
612 }
613 }
614 }
615}
616
617/// Iterator over the edges of from or to a node
618pub struct Edges<'a, E: 'a> {
619 /// starting node to skip over
620 skip_start: NodeIndex,
621 edges: &'a [Edge<E>],
622
623 /// Next edge to visit.
624 next: [EdgeIndex; 2],
625
626 /// For directed graphs: the direction to iterate in
627 /// For undirected graphs: the direction of edges
628 direction: Direction,
629}
630
631impl<'a, E> Iterator for Edges<'a, E> {
632 type Item = EdgeReference<'a, E>;
633
634 fn next(&mut self) -> Option<Self::Item> {
635 // type direction | iterate over reverse
636 // |
637 // Directed Outgoing | outgoing no
638 // Directed Incoming | incoming no
639 // Undirected Outgoing | both incoming
640 // Undirected Incoming | both outgoing
641
642 // For iterate_over, "both" is represented as None.
643 // For reverse, "no" is represented as None.
644 let (iterate_over, _reverse) = (None, Some(self.direction.opposite()));
645
646 if iterate_over.unwrap_or(Direction::Outgoing) == Direction::Outgoing {
647 let i = self.next[0].index();
648 if let Some(Edge {
649 node: _node,
650 weight,
651 next,
652 ..
653 }) = self.edges.get(i)
654 {
655 self.next[0] = next[0];
656 return Some(EdgeReference {
657 index: EdgeIndex(i as u32),
658 // node: if reverse == Some(Direction::Outgoing) {
659 // swap_pair(*node)
660 // } else {
661 // *node
662 // },
663 weight,
664 });
665 }
666 }
667
668 if iterate_over.unwrap_or(Direction::Incoming) == Direction::Incoming {
669 while let Some(Edge {
670 node, weight, next, ..
671 }) = self.edges.get(self.next[1].index())
672 {
673 let edge_index = self.next[1];
674 self.next[1] = next[1];
675 // In any of the "both" situations, self-loops would be iterated over twice.
676 // Skip them here.
677 if iterate_over.is_none() && node[0] == self.skip_start {
678 continue;
679 }
680
681 return Some(EdgeReference {
682 index: edge_index,
683 // node: if reverse == Some(Direction::Incoming) {
684 // swap_pair(*node)
685 // } else {
686 // *node
687 // },
688 weight,
689 });
690 }
691 }
692
693 None
694 }
695}
696
697// fn swap_pair<T>(mut x: [T; 2]) -> [T; 2] {
698// x.swap(0, 1);
699// x
700// }
701
702impl<E> Clone for Edges<'_, E> {
703 fn clone(&self) -> Self {
704 Edges {
705 skip_start: self.skip_start,
706 edges: self.edges,
707 next: self.next,
708 direction: self.direction,
709 }
710 }
711}
712
713/// Index the `Graph` by `NodeIndex` to access node weights.
714///
715/// **Panics** if the node doesn't exist.
716impl<N, E> Index<NodeIndex> for Graph<N, E> {
717 type Output = N;
718 fn index(&self, index: NodeIndex) -> &N {
719 &self.nodes[index.index()].weight
720 }
721}
722
723/// Index the `Graph` by `NodeIndex` to access node weights.
724///
725/// **Panics** if the node doesn't exist.
726impl<N, E> IndexMut<NodeIndex> for Graph<N, E> {
727 fn index_mut(&mut self, index: NodeIndex) -> &mut N {
728 &mut self.nodes[index.index()].weight
729 }
730}
731
732/// Index the `Graph` by `EdgeIndex` to access edge weights.
733///
734/// **Panics** if the edge doesn't exist.
735impl<N, E> Index<EdgeIndex> for Graph<N, E> {
736 type Output = E;
737 fn index(&self, index: EdgeIndex) -> &E {
738 &self.edges[index.index()].weight
739 }
740}
741
742/// Index the `Graph` by `EdgeIndex` to access edge weights.
743///
744/// **Panics** if the edge doesn't exist.
745impl<N, E> IndexMut<EdgeIndex> for Graph<N, E> {
746 fn index_mut(&mut self, index: EdgeIndex) -> &mut E {
747 &mut self.edges[index.index()].weight
748 }
749}
750
751/// Reference to a `Graph` edge.
752#[derive(Debug)]
753pub struct EdgeReference<'a, E: 'a> {
754 index: EdgeIndex,
755 // node: [NodeIndex; 2],
756 weight: &'a E,
757}
758
759impl<'a, E: 'a> EdgeReference<'a, E> {
760 #[inline]
761 pub fn id(&self) -> EdgeIndex {
762 self.index
763 }
764
765 #[inline]
766 pub fn weight(&self) -> &'a E {
767 self.weight
768 }
769}
770
771impl<E> Clone for EdgeReference<'_, E> {
772 fn clone(&self) -> Self {
773 *self
774 }
775}
776
777impl<E> Copy for EdgeReference<'_, E> {}
778
779impl<E> PartialEq for EdgeReference<'_, E>
780where
781 E: PartialEq,
782{
783 fn eq(&self, rhs: &Self) -> bool {
784 self.index == rhs.index && self.weight == rhs.weight
785 }
786}