@@ -85,6 +85,10 @@ pub struct Graph<T> {
8585 #[ cfg( feature = "dot" ) ]
8686 /// Mapping between vertices and labels
8787 vertex_labels : HashMap < VertexId , String > ,
88+
89+ #[ cfg( feature = "dot" ) ]
90+ /// Mapping between edges and labels
91+ edge_labels : HashMap < Edge , String > ,
8892}
8993
9094impl < T > Graph < T > {
@@ -110,6 +114,8 @@ impl<T> Graph<T> {
110114
111115 #[ cfg( feature = "dot" ) ]
112116 vertex_labels : HashMap :: new ( ) ,
117+ #[ cfg( feature = "dot" ) ]
118+ edge_labels : HashMap :: new ( ) ,
113119 }
114120 }
115121
@@ -138,6 +144,8 @@ impl<T> Graph<T> {
138144
139145 #[ cfg( feature = "dot" ) ]
140146 vertex_labels : HashMap :: with_capacity ( capacity) ,
147+ #[ cfg( feature = "dot" ) ]
148+ edge_labels : HashMap :: with_capacity ( capacity) ,
141149 }
142150 }
143151
@@ -202,6 +210,8 @@ impl<T> Graph<T> {
202210
203211 #[ cfg( feature = "dot" ) ]
204212 self . vertex_labels . reserve ( additional) ;
213+ #[ cfg( feature = "dot" ) ]
214+ self . edge_labels . reserve ( additional) ;
205215 }
206216
207217 /// Shrinks the capacity of the graph as much as possible.
@@ -229,6 +239,8 @@ impl<T> Graph<T> {
229239
230240 #[ cfg( feature = "dot" ) ]
231241 self . vertex_labels . shrink_to_fit ( ) ;
242+ #[ cfg( feature = "dot" ) ]
243+ self . edge_labels . shrink_to_fit ( ) ;
232244
233245 // Calculate additional value for edges vector
234246 // such that it is always n^2 where n is the
@@ -774,6 +786,7 @@ impl<T> Graph<T> {
774786 #[ cfg( feature = "dot" ) ]
775787 {
776788 graph. vertex_labels = self . vertex_labels . clone ( ) ;
789+ graph. edge_labels = self . edge_labels . clone ( ) ;
777790 }
778791
779792 graph
@@ -1382,6 +1395,42 @@ impl<T> Graph<T> {
13821395 Ok ( old_label)
13831396 }
13841397
1398+ #[ cfg( feature = "dot" ) ]
1399+ /// Labels the edge with between the given vertices. Returns the old label if successful.
1400+ ///
1401+ /// This method requires the `dot` crate feature.
1402+ ///
1403+ /// ## Example
1404+ /// ```rust
1405+ /// use graphlib::{Graph, VertexId};
1406+ ///
1407+ /// let mut graph: Graph<usize> = Graph::new();
1408+ /// let random_id = VertexId::random();
1409+ ///
1410+ /// let v1 = graph.add_vertex(0);
1411+ /// let v2 = graph.add_vertex(1);
1412+ /// let v3 = graph.add_vertex(2);
1413+ ///
1414+ /// graph.add_edge(&v1, &v2).unwrap();
1415+ /// graph.add_edge(&v3, &v1).unwrap();
1416+ ///
1417+ /// assert!(graph.add_edge_label(&v1, &v2, "V1->V2").is_ok());
1418+ /// assert!(graph.add_edge_label(&v3, &v1, "V3->V1").is_ok());
1419+ /// assert!(graph.add_edge_label(&v2, &v3, "V2->V3").is_err());
1420+ /// assert!(graph.add_edge_label(&v1, &v3, "V1->V3").is_err());
1421+ /// ```
1422+ pub fn add_edge_label ( & mut self , a : & VertexId , b : & VertexId , label : & str )
1423+ -> Result < Option < String > , GraphErr >
1424+ {
1425+ if !self . has_edge ( a, b) {
1426+ return Err ( GraphErr :: NoSuchEdge ) ;
1427+ }
1428+
1429+ let edge = Edge :: new ( a. clone ( ) , b. clone ( ) ) ;
1430+ let old_label = self . edge_labels . insert ( edge, label. to_owned ( ) ) ;
1431+ Ok ( old_label)
1432+ }
1433+
13851434 #[ cfg( feature = "dot" ) ]
13861435 /// Retrieves the label of the vertex with the given id.
13871436 ///
@@ -1392,6 +1441,16 @@ impl<T> Graph<T> {
13921441 self . vertex_labels . get ( vertex_id)
13931442 }
13941443
1444+ #[ cfg( feature = "dot" ) ]
1445+ /// Retrieves the label of the edge with the given vertices.
1446+ ///
1447+ /// This method requires the `dot` crate feature.
1448+ ///
1449+ /// Returns `None` if there is no edge associated with the given vertices in the graph.
1450+ pub fn edge_label ( & self , a : & VertexId , b : & VertexId ) -> Option < & String > {
1451+ self . edge_labels . get ( & Edge :: new ( * a, * b) )
1452+ }
1453+
13951454 #[ cfg( feature = "dot" ) ]
13961455 /// Maps each label that is placed on a vertex to a new label.
13971456 ///
@@ -1447,6 +1506,55 @@ impl<T> Graph<T> {
14471506 }
14481507 }
14491508
1509+ #[ cfg( feature = "dot" ) ]
1510+ /// Maps each label that is placed on an edge to a new label.
1511+ ///
1512+ /// This method requires the `dot` crate feature.
1513+ ///
1514+ /// ```rust
1515+ /// use std::collections::HashMap;
1516+ /// use graphlib::{Graph, VertexId};
1517+ ///
1518+ /// let mut graph: Graph<usize> = Graph::new();
1519+ /// let random_id = VertexId::random();
1520+ /// let mut vertex_id: usize = 1;
1521+ ///
1522+ /// let v1 = graph.add_vertex(0);
1523+ /// let v2 = graph.add_vertex(1);
1524+ /// let v3 = graph.add_vertex(2);
1525+ /// let v4 = graph.add_vertex(3);
1526+ ///
1527+ /// graph.add_edge(&v1, &v2).unwrap();
1528+ /// graph.add_edge(&v2, &v3).unwrap();
1529+ /// graph.add_edge(&v1, &v4).unwrap();
1530+ /// graph.add_edge(&v4, &v3).unwrap();
1531+ ///
1532+ /// assert!(graph.add_edge_label(&v1, &v2, &"V1->V2").is_ok());
1533+ /// assert!(graph.add_edge_label(&v2, &v3, &"V2->V3").is_ok());
1534+ /// assert!(graph.add_edge_label(&v1, &v4, &"V1->V4").is_ok());
1535+ /// assert!(graph.add_edge_label(&v4, &v3, &"V4->V3").is_ok());
1536+ /// assert!(graph.add_edge_label(&v1, &v3, &"V1->V3").is_err());
1537+ ///
1538+ /// assert_eq!(graph.edge_label(&v1, &v2).unwrap(), "V1->V2");
1539+ /// assert_eq!(graph.edge_label(&v2, &v3).unwrap(), "V2->V3");
1540+ /// assert_eq!(graph.edge_label(&v1, &v4).unwrap(), "V1->V4");
1541+ /// assert_eq!(graph.edge_label(&v4, &v3).unwrap(), "V4->V3");
1542+ ///
1543+ /// graph.map_edge_labels(|edge, old_label| format!("*{}*", old_label.unwrap()));
1544+ ///
1545+ /// assert_eq!(graph.edge_label(&v1, &v2).unwrap(), "*V1->V2*");
1546+ /// assert_eq!(graph.edge_label(&v2, &v3).unwrap(), "*V2->V3*");
1547+ /// assert_eq!(graph.edge_label(&v1, &v4).unwrap(), "*V1->V4*");
1548+ /// assert_eq!(graph.edge_label(&v4, &v3).unwrap(), "*V4->V3*");
1549+ /// ```
1550+ pub fn map_edge_labels ( & mut self , mut fun : impl FnMut ( & Edge , Option < & str > ) -> String ) {
1551+ for ( edge, _) in self . edges . iter ( ) {
1552+ self . edge_labels . entry ( Edge :: new ( * edge. outbound ( ) , * edge. inbound ( ) ) )
1553+ . and_modify ( |e| { * e = fun ( edge, Some ( e) ) ; } )
1554+ . or_insert_with ( || fun ( edge, None ) ) ;
1555+ }
1556+ }
1557+
14501558 fn do_add_edge (
14511559 & mut self ,
14521560 a : & VertexId ,
0 commit comments