ddgg/
graph.rs

1use core::{fmt::Debug, mem, ops};
2
3use alloc::vec::Vec;
4
5#[cfg(feature = "serde")]
6use serde::{Deserialize, Serialize};
7use snafu::OptionExt;
8
9use crate::{
10    errors::GraphError,
11    gen_vec::{Element, GenVec, Index},
12    graph_diff::{
13        AddEdge, AddVertex, GraphDiff, RemoveEdge, RemoveVertex, UpdateEdgeData, UpdateVertexData,
14    },
15    EdgeDoesNotExistSnafu, VertexDoesNotExistSnafu,
16};
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
19#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
20pub struct VertexIndex(pub(crate) Index);
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
22#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
23pub struct EdgeIndex(pub(crate) Index);
24
25#[derive(Debug, Clone)]
26#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
27#[cfg_attr(feature = "js_names", serde(rename_all = "camelCase"))]
28pub struct Vertex<T> {
29    connections_from: Vec<(VertexIndex, EdgeIndex)>,
30    connections_to: Vec<(VertexIndex, EdgeIndex)>,
31    data: T,
32}
33
34impl<T> Vertex<T> {
35    fn new(data: T) -> Vertex<T> {
36        Vertex {
37            connections_from: Vec::new(),
38            connections_to: Vec::new(),
39            data,
40        }
41    }
42
43    pub fn get_connections_from(&self) -> &Vec<(VertexIndex, EdgeIndex)> {
44        &self.connections_from
45    }
46
47    pub fn get_connections_to(&self) -> &Vec<(VertexIndex, EdgeIndex)> {
48        &self.connections_to
49    }
50
51    pub fn data(&self) -> &T {
52        &self.data
53    }
54
55    fn add_from_unchecked(&mut self, from: VertexIndex, edge: EdgeIndex) {
56        self.connections_from.push((from, edge));
57    }
58
59    fn add_to_unchecked(&mut self, to: VertexIndex, edge: EdgeIndex) {
60        self.connections_to.push((to, edge));
61    }
62
63    fn remove_from(&mut self, edge_index: EdgeIndex) -> Result<(), ()> {
64        let position = self
65            .connections_from
66            .iter()
67            .position(|connection| connection.1 == edge_index)
68            .ok_or(())?;
69
70        self.connections_from.remove(position);
71
72        Ok(())
73    }
74
75    fn remove_to(&mut self, edge_index: EdgeIndex) -> Result<(), ()> {
76        let position = self
77            .connections_to
78            .iter()
79            .position(|connection| connection.1 == edge_index)
80            .ok_or(())?;
81
82        self.connections_to.remove(position);
83
84        Ok(())
85    }
86}
87
88#[derive(Debug, Clone)]
89#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
90#[cfg_attr(feature = "js_names", serde(rename_all = "camelCase"))]
91pub struct Edge<T> {
92    from: VertexIndex,
93    to: VertexIndex,
94    data: T,
95}
96
97impl<T> Edge<T> {
98    pub fn new(from: VertexIndex, to: VertexIndex, data: T) -> Edge<T> {
99        Edge { from, to, data }
100    }
101
102    pub fn get_from(&self) -> VertexIndex {
103        self.from
104    }
105
106    pub fn get_to(&self) -> VertexIndex {
107        self.to
108    }
109
110    pub fn data(&self) -> &T {
111        &self.data
112    }
113}
114
115/// Main graph structure
116#[derive(Debug, Clone)]
117#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
118#[cfg_attr(feature = "js_names", serde(rename_all = "camelCase"))]
119pub struct Graph<V, E> {
120    verticies: GenVec<Vertex<V>>,
121    edges: GenVec<Edge<E>>,
122}
123
124impl<V, E> Graph<V, E> {
125    pub fn from_constraints() -> Graph<V, E> {
126        Graph {
127            verticies: GenVec::new(),
128            edges: GenVec::new(),
129        }
130    }
131}
132
133impl<V: Clone, E: Clone> Graph<V, E> {
134    pub fn new() -> Graph<V, E> {
135        Graph {
136            verticies: GenVec::new(),
137            edges: GenVec::new(),
138        }
139    }
140
141    pub fn add_vertex(&mut self, vertex_data: V) -> (VertexIndex, GraphDiff<V, E>) {
142        let vertex_index = VertexIndex(self.verticies.add(Vertex::new(vertex_data.clone())));
143
144        let diff = AddVertex {
145            vertex_index,
146            vertex_data,
147        };
148
149        (vertex_index, GraphDiff::AddVertex(diff))
150    }
151
152    pub fn add_edge(
153        &mut self,
154        from_index: VertexIndex,
155        to_index: VertexIndex,
156        edge_data: E,
157    ) -> Result<(EdgeIndex, GraphDiff<V, E>), GraphError> {
158        self.assert_vertex_exists(from_index)?;
159        self.assert_vertex_exists(to_index)?;
160
161        // create the edge and link everything up
162        let edge_index = EdgeIndex(self.edges.add(Edge::new(
163            from_index,
164            to_index,
165            edge_data.clone(),
166        )));
167
168        // connect the verticies (all vertex lookups use unwraps here to preserve the invariant of two-way connections)
169        self[from_index].add_to_unchecked(to_index, edge_index);
170        self[to_index].add_from_unchecked(from_index, edge_index);
171
172        let diff = AddEdge {
173            edge_index: edge_index,
174            from: from_index,
175            to: to_index,
176            edge_data,
177        };
178
179        Ok((edge_index, GraphDiff::AddEdge(diff)))
180    }
181
182    pub fn update_vertex(
183        &mut self,
184        index: VertexIndex,
185        value: V,
186    ) -> Result<(V, GraphDiff<V, E>), GraphError> {
187        let vertex = self
188            .get_vertex_mut(index)
189            .context(VertexDoesNotExistSnafu { index })?;
190
191        let old_value = mem::replace(&mut vertex.data, value.clone());
192
193        Ok((
194            old_value.clone(),
195            GraphDiff::UpdateVertexData(UpdateVertexData {
196                index,
197                before: old_value,
198                after: value,
199            }),
200        ))
201    }
202
203    pub fn update_edge(
204        &mut self,
205        index: EdgeIndex,
206        value: E,
207    ) -> Result<(E, GraphDiff<V, E>), GraphError> {
208        let edge = self
209            .get_edge_mut(index)
210            .context(EdgeDoesNotExistSnafu { index })?;
211
212        let old_value = mem::replace(&mut edge.data, value.clone());
213
214        Ok((
215            old_value.clone(),
216            GraphDiff::UpdateEdgeData(UpdateEdgeData {
217                index,
218                before: old_value,
219                after: value,
220            }),
221        ))
222    }
223
224    pub fn remove_edge(
225        &mut self,
226        edge_index: EdgeIndex,
227    ) -> Result<(E, GraphDiff<V, E>), GraphError> {
228        self.remove_edge_internal(edge_index)
229            .map(|(edge, diff)| (edge, GraphDiff::RemoveEdge(diff)))
230    }
231
232    fn remove_edge_internal(
233        &mut self,
234        edge_index: EdgeIndex,
235    ) -> Result<(E, RemoveEdge<E>), GraphError> {
236        let edge = self
237            .get_edge(edge_index)
238            .with_context(|| EdgeDoesNotExistSnafu { index: edge_index })?;
239
240        let from_index = edge.from;
241        let to_index = edge.to;
242
243        // remove the edge (all vertex lookups use unwraps here to preserve the invariant of two-way connections)
244        self[from_index].remove_to(edge_index).unwrap();
245        self[to_index].remove_from(edge_index).unwrap();
246
247        let edge = self.edges.remove(edge_index.0).unwrap();
248        let edge_data = edge.data.clone();
249
250        let diff = RemoveEdge {
251            edge_index,
252            edge: edge,
253        };
254
255        Ok((edge_data, diff))
256    }
257
258    pub fn remove_vertex(
259        &mut self,
260        vertex_index: VertexIndex,
261    ) -> Result<(V, GraphDiff<V, E>), GraphError> {
262        // check that everything is in proper order
263        let vertex = self
264            .get_vertex(vertex_index)
265            .with_context(|| VertexDoesNotExistSnafu {
266                index: vertex_index,
267            })?;
268
269        // remove all connections to the vertex
270        let mut connections = vertex.get_connections_from().clone();
271        connections.extend(vertex.get_connections_to().clone());
272
273        let edge_diffs: Vec<RemoveEdge<E>> = connections
274            .iter()
275            .map(|(_, connection_index)| self.remove_edge_internal(*connection_index).unwrap().1)
276            .collect();
277
278        // finally remove the vertex
279        let vertex = self.verticies.remove(vertex_index.0).unwrap();
280        let vertex_data = vertex.data.clone();
281
282        let diff = GraphDiff::RemoveVertex(RemoveVertex {
283            vertex_index,
284            vertex,
285            removed_edges: edge_diffs,
286        });
287
288        Ok((vertex_data, diff))
289    }
290
291    pub fn apply_diff(&mut self, diff: GraphDiff<V, E>) -> Result<(), GraphError> {
292        match diff {
293            GraphDiff::AddVertex(diff) => self.apply_add_vertex_diff(diff),
294            GraphDiff::AddEdge(diff) => self.apply_add_edge_diff(diff),
295            GraphDiff::UpdateVertexData(diff) => self.apply_update_vertex_diff(diff),
296            GraphDiff::UpdateEdgeData(diff) => self.apply_update_edge_diff(diff),
297            GraphDiff::RemoveEdge(diff) => self.apply_remove_edge_diff(diff),
298            GraphDiff::RemoveVertex(diff) => self.apply_remove_vertex_diff(diff),
299        }
300    }
301
302    pub fn rollback_diff(&mut self, diff: GraphDiff<V, E>) -> Result<(), GraphError> {
303        match diff {
304            GraphDiff::AddVertex(add_vertex) => self.rollback_add_vertex_diff(add_vertex),
305            GraphDiff::AddEdge(add_edge) => self.rollback_add_edge_diff(add_edge),
306            GraphDiff::UpdateVertexData(diff) => self.rollback_update_vertex_diff(diff),
307            GraphDiff::UpdateEdgeData(diff) => self.rollback_update_edge_diff(diff),
308            GraphDiff::RemoveEdge(remove_edge) => self.rollback_remove_edge_diff(remove_edge),
309            GraphDiff::RemoveVertex(remove_vertex) => {
310                self.rollback_remove_vertex_diff(remove_vertex)
311            }
312        }
313    }
314}
315
316// Utility functions
317impl<V: Clone, E: Clone> Graph<V, E> {
318    pub fn get_vertex(&self, index: VertexIndex) -> Option<&Vertex<V>> {
319        self.verticies.get(index.0)
320    }
321
322    pub fn get_vertex_data(&self, index: VertexIndex) -> Option<&V> {
323        Some(&self.get_vertex(index)?.data)
324    }
325
326    fn get_vertex_mut(&mut self, index: VertexIndex) -> Option<&mut Vertex<V>> {
327        self.verticies.get_mut(index.0)
328    }
329
330    /// Note: changes here will *not* be tracked. It's usually better to use
331    /// [`Graph::update_vertex`]
332    pub fn get_vertex_data_mut(&mut self, index: VertexIndex) -> Option<&mut V> {
333        Some(&mut self.get_vertex_mut(index)?.data)
334    }
335
336    pub fn get_edge(&self, index: EdgeIndex) -> Option<&Edge<E>> {
337        self.edges.get(index.0)
338    }
339
340    pub fn get_edge_data(&self, index: EdgeIndex) -> Option<&E> {
341        Some(&self.get_edge(index)?.data)
342    }
343
344    /// Note: changes here will *not* be tracked. It's usually better to use
345    /// [`Graph::update_edge`]
346    pub fn get_edge_data_mut(&mut self, index: EdgeIndex) -> Option<&mut E> {
347        Some(&mut self.get_edge_mut(index)?.data)
348    }
349
350    fn get_edge_mut(&mut self, index: EdgeIndex) -> Option<&mut Edge<E>> {
351        self.edges.get_mut(index.0)
352    }
353
354    /// Check that a vertex exists. Returns a result containing `VertexDoesNotExist` if it doesn't exist
355    pub fn assert_vertex_exists(&self, index: VertexIndex) -> Result<(), GraphError> {
356        if self.verticies.get(index.0).is_none() {
357            Err(GraphError::VertexDoesNotExist { index })
358        } else {
359            Ok(())
360        }
361    }
362
363    // Check that an edge exists. Returns a result containing `EdgeDoesNotExist` if it doesn't exist
364    pub fn assert_edge_exists(&self, index: EdgeIndex) -> Result<(), GraphError> {
365        if self.edges.get(index.0).is_none() {
366            Err(GraphError::EdgeDoesNotExist { index })
367        } else {
368            Ok(())
369        }
370    }
371
372    /// Get a list of edges between two nodes. This only returns connections in one direction.
373    pub fn shared_edges(
374        &self,
375        from: VertexIndex,
376        to: VertexIndex,
377    ) -> Result<impl Iterator<Item = EdgeIndex> + '_, GraphError> {
378        Ok(self
379            .get_vertex(from)
380            .with_context(|| VertexDoesNotExistSnafu { index: from })?
381            .get_connections_to()
382            .iter()
383            .filter(move |connection| connection.0 == to)
384            .map(|connection| connection.1))
385    }
386
387    pub fn get_verticies(&self) -> &GenVec<Vertex<V>> {
388        &self.verticies
389    }
390
391    pub fn get_edges(&self) -> &GenVec<Edge<E>> {
392        &self.edges
393    }
394
395    pub fn vertex_indexes(&self) -> impl Iterator<Item = VertexIndex> + '_ {
396        self.verticies.indexes().map(|index| VertexIndex(index))
397    }
398
399    pub fn edge_indexes(&self) -> impl Iterator<Item = EdgeIndex> + '_ {
400        self.edges.indexes().map(|index| EdgeIndex(index))
401    }
402
403    pub fn vertex_iter(&self) -> impl Iterator<Item = (VertexIndex, &Vertex<V>)> + '_ {
404        self.verticies
405            .iter()
406            .map(|(index, vertex)| (VertexIndex(index), vertex))
407    }
408
409    pub fn edge_iter(&self) -> impl Iterator<Item = (EdgeIndex, &Edge<E>)> + '_ {
410        self.edges
411            .iter()
412            .map(|(index, edge)| (EdgeIndex(index), edge))
413    }
414
415    pub fn vertex_data_iter(&self) -> impl Iterator<Item = (VertexIndex, &V)> + '_ {
416        self.verticies
417            .iter()
418            .map(|(index, vertex)| (VertexIndex(index), &vertex.data))
419    }
420
421    pub fn edge_data_iter(&self) -> impl Iterator<Item = (EdgeIndex, &E)> + '_ {
422        self.edges
423            .iter()
424            .map(|(index, edge)| (EdgeIndex(index), &edge.data))
425    }
426
427    fn apply_add_vertex_diff(&mut self, diff: AddVertex<V>) -> Result<(), GraphError> {
428        if !self
429            .verticies
430            .is_replaceable_by_index_apply(diff.vertex_index.0)
431        {
432            return Err(GraphError::InvalidDiff);
433        }
434
435        self.verticies.vec_ref_mut()[diff.vertex_index.0.index] = Element::Occupied(
436            Vertex::new(diff.vertex_data),
437            diff.vertex_index.0.generation,
438        );
439
440        Ok(())
441    }
442
443    fn apply_add_edge_diff(&mut self, diff: AddEdge<E>) -> Result<(), GraphError> {
444        self.assert_vertex_exists(diff.from)?;
445        self.assert_vertex_exists(diff.to)?;
446
447        // check that this edge doesn't exist
448        if !self.edges.is_replaceable_by_index_apply(diff.edge_index.0) {
449            return Err(GraphError::InvalidDiff);
450        }
451
452        // apply the diff
453        self.edges.vec_ref_mut()[diff.edge_index.0.index] = Element::Occupied(
454            Edge::new(diff.from, diff.to, diff.edge_data),
455            diff.edge_index.0.generation,
456        );
457
458        let from = self
459            .get_vertex_mut(diff.from)
460            .expect("Graph state has become corrupted before applying diff");
461        from.add_to_unchecked(diff.to, diff.edge_index);
462
463        let to = self
464            .get_vertex_mut(diff.to)
465            .expect("Graph state has become corrupted before applying diff");
466        to.add_from_unchecked(diff.from, diff.edge_index);
467
468        Ok(())
469    }
470
471    fn apply_update_vertex_diff(&mut self, diff: UpdateVertexData<V>) -> Result<(), GraphError> {
472        let vertex = self
473            .get_vertex_mut(diff.index)
474            .context(VertexDoesNotExistSnafu { index: diff.index })?;
475
476        vertex.data = diff.after;
477
478        Ok(())
479    }
480
481    fn apply_update_edge_diff(&mut self, diff: UpdateEdgeData<E>) -> Result<(), GraphError> {
482        let edge = self
483            .get_edge_mut(diff.index)
484            .context(EdgeDoesNotExistSnafu { index: diff.index })?;
485
486        edge.data = diff.after;
487
488        Ok(())
489    }
490
491    fn apply_remove_edge_diff(&mut self, diff: RemoveEdge<E>) -> Result<(), GraphError> {
492        self.assert_vertex_exists(diff.edge.from)?;
493        self.assert_vertex_exists(diff.edge.to)?;
494        self.assert_edge_exists(diff.edge_index)?;
495
496        // remove the edge
497        self.remove_edge(diff.edge_index)
498            .expect("Graph state has become corrupted before applying diff");
499
500        Ok(())
501    }
502
503    fn apply_remove_vertex_diff(&mut self, diff: RemoveVertex<V, E>) -> Result<(), GraphError> {
504        self.assert_vertex_exists(diff.vertex_index)?;
505
506        self.remove_vertex(diff.vertex_index)
507            .expect("Graph state has become corrupted before applying diff");
508
509        Ok(())
510    }
511
512    fn rollback_add_vertex_diff(&mut self, diff: AddVertex<V>) -> Result<(), GraphError> {
513        // check that the vertex exists
514        self.assert_vertex_exists(diff.vertex_index)?;
515
516        self.remove_vertex_and_reset(diff.vertex_index)
517            .expect("Graph state has become corrupted before applying diff");
518
519        Ok(())
520    }
521
522    fn rollback_add_edge_diff(&mut self, diff: AddEdge<E>) -> Result<(), GraphError> {
523        self.assert_vertex_exists(diff.from)?;
524        self.assert_vertex_exists(diff.to)?;
525        self.assert_edge_exists(diff.edge_index)?;
526
527        // remove the edge
528        self.remove_edge_and_reset(diff.edge_index)
529            .expect("Graph state has become corrupted before applying diff");
530
531        Ok(())
532    }
533
534    fn rollback_update_vertex_diff(&mut self, diff: UpdateVertexData<V>) -> Result<(), GraphError> {
535        let vertex = self
536            .get_vertex_mut(diff.index)
537            .context(VertexDoesNotExistSnafu { index: diff.index })?;
538
539        vertex.data = diff.before;
540
541        Ok(())
542    }
543
544    fn rollback_update_edge_diff(&mut self, diff: UpdateEdgeData<E>) -> Result<(), GraphError> {
545        let edge = self
546            .get_edge_mut(diff.index)
547            .context(EdgeDoesNotExistSnafu { index: diff.index })?;
548
549        edge.data = diff.before;
550
551        Ok(())
552    }
553
554    fn rollback_remove_edge_diff(&mut self, diff: RemoveEdge<E>) -> Result<(), GraphError> {
555        let from_index = diff.edge.from;
556        let to_index = diff.edge.to;
557
558        self.assert_vertex_exists(from_index)?;
559        self.assert_vertex_exists(to_index)?;
560
561        // check that this edge doesn't exist
562        if !self
563            .edges
564            .is_replaceable_by_index_rollback(diff.edge_index.0)
565        {
566            return Err(GraphError::InvalidDiff);
567        }
568
569        // apply the diff
570        self.edges.vec_ref_mut()[diff.edge_index.0.index] =
571            Element::Occupied(diff.edge, diff.edge_index.0.generation);
572
573        let from = self
574            .get_vertex_mut(from_index)
575            .expect("Graph state has become corrupted before applying diff");
576        from.add_to_unchecked(to_index, diff.edge_index);
577
578        let to = self
579            .get_vertex_mut(to_index)
580            .expect("Graph state has become corrupted before applying diff");
581        to.add_from_unchecked(from_index, diff.edge_index);
582
583        Ok(())
584    }
585
586    fn rollback_remove_vertex_diff(&mut self, diff: RemoveVertex<V, E>) -> Result<(), GraphError> {
587        if !self
588            .verticies
589            .is_replaceable_by_index_rollback(diff.vertex_index.0)
590        {
591            return Err(GraphError::InvalidDiff);
592        }
593
594        // check that all edges are replaceable
595        for removed_edge in diff.removed_edges.iter() {
596            if !self
597                .edges
598                .is_replaceable_by_index_rollback(removed_edge.edge_index.0)
599            {
600                return Err(GraphError::InvalidDiff);
601            }
602        }
603
604        self.verticies.vec_ref_mut()[diff.vertex_index.0.index] =
605            Element::Occupied(diff.vertex, diff.vertex_index.0.generation);
606
607        for removed_edge in diff.removed_edges {
608            let from = self
609                .get_vertex_mut(removed_edge.edge.from)
610                .expect("Graph state has become corrupted before applying diff");
611            from.add_to_unchecked(removed_edge.edge.to, removed_edge.edge_index);
612
613            let to = self
614                .get_vertex_mut(removed_edge.edge.to)
615                .expect("Graph state has become corrupted before applying diff");
616            to.add_from_unchecked(removed_edge.edge.from, removed_edge.edge_index);
617
618            self.edges.vec_ref_mut()[removed_edge.edge_index.0.index] =
619                Element::Occupied(removed_edge.edge, removed_edge.edge_index.0.generation);
620        }
621
622        Ok(())
623    }
624
625    fn remove_vertex_and_reset(&mut self, index: VertexIndex) -> Result<V, GraphError> {
626        // check that everything is in proper order
627        let vertex = self
628            .get_vertex(index)
629            .with_context(|| VertexDoesNotExistSnafu { index })?;
630
631        // remove all connections to the vertex
632        let mut connections = vertex.get_connections_from().clone();
633        connections.extend(vertex.get_connections_to().clone());
634
635        for (_, edge_index) in connections {
636            self.remove_edge_and_reset(edge_index).unwrap();
637        }
638
639        // finally remove the vertex
640        let vertex = self.verticies.remove_keep_generation(index.0).unwrap();
641        let vertex_data = vertex.data.clone();
642
643        Ok(vertex_data)
644    }
645
646    fn remove_edge_and_reset(&mut self, edge_index: EdgeIndex) -> Result<E, GraphError> {
647        let edge = self
648            .get_edge(edge_index)
649            .with_context(|| EdgeDoesNotExistSnafu { index: edge_index })?;
650        let from_index = edge.from;
651        let to_index = edge.to;
652
653        // remove the edge (all vertex lookups use unwraps here to preserve the invariant of two-way connections)
654        let from = self.get_vertex_mut(from_index).unwrap();
655        from.remove_to(edge_index).unwrap();
656
657        let to = self.get_vertex_mut(to_index).unwrap();
658        to.remove_from(edge_index).unwrap();
659
660        let edge = self.edges.remove_keep_generation(edge_index.0).unwrap();
661
662        Ok(edge.data)
663    }
664}
665
666impl<V: Clone, E: Clone> Default for Graph<V, E> {
667    fn default() -> Self {
668        Graph::new()
669    }
670}
671
672impl<V: Clone, E: Clone> ops::Index<VertexIndex> for Graph<V, E> {
673    type Output = Vertex<V>;
674
675    fn index(&self, index: VertexIndex) -> &Self::Output {
676        self.get_vertex(index).unwrap()
677    }
678}
679
680impl<V: Clone, E: Clone> ops::IndexMut<VertexIndex> for Graph<V, E> {
681    fn index_mut(&mut self, index: VertexIndex) -> &mut Self::Output {
682        self.get_vertex_mut(index).unwrap()
683    }
684}
685
686impl<V: Clone, E: Clone> ops::Index<EdgeIndex> for Graph<V, E> {
687    type Output = Edge<E>;
688
689    fn index(&self, index: EdgeIndex) -> &Self::Output {
690        self.get_edge(index).unwrap()
691    }
692}
693
694impl<V: Clone, E: Clone> ops::IndexMut<EdgeIndex> for Graph<V, E> {
695    fn index_mut(&mut self, index: EdgeIndex) -> &mut Self::Output {
696        self.get_edge_mut(index).unwrap()
697    }
698}