diff --git a/src/lib.rs b/src/lib.rs index 1fadff8..2a0a884 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -145,8 +145,8 @@ pub mod traits; /// Convenience re-exports of graph topology traits for common use. pub mod prelude { pub use crate::traits::{ - FromGraph, GraphTopology, GraphTopologyAddition, GraphTopologyDeletion, Incidence, - IncidenceCursor, + GraphTopology, GraphTopologyAddition, GraphTopologyConversion, GraphTopologyDeletion, + Incidence, IncidenceCursor, }; } diff --git a/src/models.rs b/src/models.rs index 3c55fbd..5274bbc 100644 --- a/src/models.rs +++ b/src/models.rs @@ -17,14 +17,15 @@ pub use graph::{Graph, GraphEdgeMap, GraphIncidence, GraphVertexMap}; /// Builds a new graph isomorphic to `source`. /// -/// The resulting graph type `G` must implement [`GraphTopologyAddition`] which is used to add +/// The resulting graph type `G` implements [`GraphTopologyAddition`] which is used to add /// vertices and edges. `on_edge` is called for each edge in `source` together with the /// corresponding new edge of the new graph, which callers can use to construct an edge mapping. /// -/// Used by the [`GraphTopologyAddition`] models' `From<&H>` and [`FromGraph`] implementations. +/// Used by the [`GraphTopologyAddition`] models' `From<&H>` and [`GraphTopologyConversion`] +/// implementations. /// -/// [`FromGraph`]: crate::traits::FromGraph -pub(crate) fn build_from_topology( +/// [`GraphTopologyConversion`]: crate::traits::GraphTopologyConversion +pub(crate) fn convert_to_addition( source: &H, vertex_default: G::Vertex, mut on_edge: impl FnMut(H::Edge, G::Edge), diff --git a/src/models/append_graph.rs b/src/models/append_graph.rs index 58b7c2f..1dd03db 100644 --- a/src/models/append_graph.rs +++ b/src/models/append_graph.rs @@ -4,7 +4,9 @@ use std::num::NonZeroUsize; use crate::maps::ElementMap; use crate::models; -use crate::traits::{FromGraph, GraphTopology, GraphTopologyAddition, Incidence, IncidenceCursor}; +use crate::traits::{ + GraphTopology, GraphTopologyAddition, GraphTopologyConversion, Incidence, IncidenceCursor, +}; /// An opaque handle identifying a vertex in an [`AppendGraph`]. /// @@ -260,14 +262,8 @@ impl GraphTopologyAddition for AppendGraph { } } -impl From<&H> for AppendGraph { - fn from(source: &H) -> Self { - models::build_from_topology::(source, Vertex(usize::MAX), |_, _| {}).0 - } -} - -impl FromGraph for AppendGraph { - fn from_graph( +impl GraphTopologyConversion for AppendGraph { + fn convert( source: &H, ) -> ( Self, @@ -276,11 +272,17 @@ impl FromGraph for AppendGraph { ) { let mut edge_map = source.edge_map(Edge(NonZeroUsize::MAX)); let (result, vertex_map) = - models::build_from_topology(source, Vertex(usize::MAX), |e, new_e| edge_map[e] = new_e); + models::convert_to_addition(source, Vertex(usize::MAX), |e, new_e| edge_map[e] = new_e); (result, vertex_map, edge_map) } } +impl From<&H> for AppendGraph { + fn from(source: &H) -> Self { + models::convert_to_addition::(source, Vertex(usize::MAX), |_, _| {}).0 + } +} + #[cfg(test)] mod trait_tests { use super::AppendGraph; @@ -290,8 +292,9 @@ mod trait_tests { crate::graph_topology_addition_tests!(AppendGraph); crate::graph_topology_clone_tests!(AppendGraph); crate::graph_topology_addition_clone_tests!(AppendGraph); - crate::graph_topology_from_graph_tests!(AppendGraph, Graph); - crate::graph_topology_addition_from_graph_tests!(AppendGraph, Graph); + crate::graph_topology_conversion_tests!(AppendGraph, Graph); + crate::graph_topology_addition_conversion_tests!(AppendGraph, Graph); + crate::from_tests!(AppendGraph, Graph); } #[cfg(test)] diff --git a/src/models/frozen_graph.rs b/src/models/frozen_graph.rs index a7ca9b1..eeaa08e 100644 --- a/src/models/frozen_graph.rs +++ b/src/models/frozen_graph.rs @@ -3,7 +3,7 @@ use std::ops::IndexMut; use crate::maps::ElementMap; -use crate::traits::{FromGraph, GraphTopology, Incidence, IncidenceCursor}; +use crate::traits::{GraphTopology, GraphTopologyConversion, Incidence, IncidenceCursor}; /// An opaque handle identifying a vertex in a [`FrozenGraph`]. /// @@ -77,7 +77,7 @@ impl IncidenceCursor for FrozenGraphIncidenceCursor { /// let u = graph.add_vertex(); /// let v = graph.add_vertex(); /// let e = graph.add_edge(u, v); -/// let (graph, vertex_map, edge_map) = FrozenGraph::from_graph(&graph); +/// let (graph, vertex_map, edge_map) = FrozenGraph::convert(&graph); /// /// // Queries the FrozenGraph instance via the returned map. /// assert!(graph.are_adjacent(vertex_map[u], vertex_map[v])); @@ -191,14 +191,8 @@ impl GraphTopology for FrozenGraph { } } -impl From<&G> for FrozenGraph { - fn from(graph: &G) -> Self { - Self::from_graph(graph).0 - } -} - -impl FromGraph for FrozenGraph { - fn from_graph( +impl GraphTopologyConversion for FrozenGraph { + fn convert( source: &G, ) -> ( Self, @@ -253,6 +247,12 @@ impl FromGraph for FrozenGraph { } } +impl From<&G> for FrozenGraph { + fn from(graph: &G) -> Self { + Self::convert(graph).0 + } +} + #[cfg(test)] mod trait_tests { use super::FrozenGraph; @@ -260,7 +260,8 @@ mod trait_tests { crate::graph_topology_tests!(FrozenGraph); crate::graph_topology_clone_tests!(FrozenGraph); - crate::graph_topology_from_graph_tests!(FrozenGraph, AppendGraph); + crate::graph_topology_conversion_tests!(FrozenGraph, AppendGraph); + crate::from_tests!(FrozenGraph, AppendGraph); } #[cfg(test)] diff --git a/src/models/graph.rs b/src/models/graph.rs index eb96813..4b85360 100644 --- a/src/models/graph.rs +++ b/src/models/graph.rs @@ -6,8 +6,8 @@ use typed_generational_arena::{Arena, Index}; use crate::maps::ElementMap; use crate::models; use crate::traits::{ - FromGraph, GraphTopology, GraphTopologyAddition, GraphTopologyDeletion, Incidence, - IncidenceCursor, + GraphTopology, GraphTopologyAddition, GraphTopologyConversion, GraphTopologyDeletion, + Incidence, IncidenceCursor, }; /// An opaque handle identifying a vertex in a [`Graph`]. @@ -400,19 +400,8 @@ impl GraphTopologyDeletion for Graph { } } -impl From<&H> for Graph { - fn from(source: &H) -> Self { - models::build_from_topology::( - source, - Vertex::new(usize::MAX, usize::MAX), - |_, _| {}, - ) - .0 - } -} - -impl FromGraph for Graph { - fn from_graph( +impl GraphTopologyConversion for Graph { + fn convert( source: &H, ) -> ( Self, @@ -421,13 +410,24 @@ impl FromGraph for Graph { ) { let mut edge_map = source.edge_map(Edge::new(usize::MAX, usize::MAX)); let (result, vertex_map) = - models::build_from_topology(source, Vertex::new(usize::MAX, usize::MAX), |e, new_e| { + models::convert_to_addition(source, Vertex::new(usize::MAX, usize::MAX), |e, new_e| { edge_map[e] = new_e }); (result, vertex_map, edge_map) } } +impl From<&H> for Graph { + fn from(source: &H) -> Self { + models::convert_to_addition::( + source, + Vertex::new(usize::MAX, usize::MAX), + |_, _| {}, + ) + .0 + } +} + #[cfg(test)] mod trait_tests { use super::Graph; @@ -439,8 +439,9 @@ mod trait_tests { crate::graph_topology_addition_deletion_tests!(Graph); crate::graph_topology_clone_tests!(Graph); crate::graph_topology_addition_clone_tests!(Graph); - crate::graph_topology_from_graph_tests!(Graph, AppendGraph); - crate::graph_topology_addition_from_graph_tests!(Graph, AppendGraph); + crate::graph_topology_conversion_tests!(Graph, AppendGraph); + crate::graph_topology_addition_conversion_tests!(Graph, AppendGraph); + crate::from_tests!(Graph, AppendGraph); } #[cfg(test)] diff --git a/src/testing.rs b/src/testing.rs index 8a841dd..5d54232 100644 --- a/src/testing.rs +++ b/src/testing.rs @@ -1,11 +1,12 @@ //! Test fixture and test macros for graph topology and algorithm implementations. pub mod fixtures; +pub mod from_testing; pub mod graph_topology_addition_clone_testing; +pub mod graph_topology_addition_conversion_testing; pub mod graph_topology_addition_deletion_testing; -pub mod graph_topology_addition_from_graph_testing; pub mod graph_topology_addition_testing; pub mod graph_topology_clone_testing; +pub mod graph_topology_conversion_testing; pub mod graph_topology_deletion_testing; -pub mod graph_topology_from_graph_testing; pub mod graph_topology_testing; diff --git a/src/testing/fixtures.rs b/src/testing/fixtures.rs index 048d088..6f49f82 100644 --- a/src/testing/fixtures.rs +++ b/src/testing/fixtures.rs @@ -2,7 +2,7 @@ use std::fmt::Debug; use crate::maps::ElementMap; use crate::models::{AppendGraph, FrozenGraph}; -use crate::traits::{FromGraph, GraphTopology, GraphTopologyAddition, Incidence}; +use crate::traits::{GraphTopology, GraphTopologyAddition, GraphTopologyConversion, Incidence}; pub trait MakeTestGraph: GraphTopology + Sized { fn standard() -> ( @@ -175,7 +175,7 @@ impl MakeTestGraph for FrozenGraph { [Vec>; 10], ) { let (build, vertices, edges, incidences) = AppendGraph::standard(); - let (graph, vertex_map, edge_map) = FrozenGraph::from_graph(&build); + let (graph, vertex_map, edge_map) = FrozenGraph::convert(&build); ( graph, vertices.map(|v| vertex_map[v]), @@ -197,31 +197,31 @@ impl MakeTestGraph for FrozenGraph { fn single_vertex() -> (Self, Self::Vertex) { let (build, v) = AppendGraph::single_vertex(); - let (graph, vertex_map, _) = FrozenGraph::from_graph(&build); + let (graph, vertex_map, _) = FrozenGraph::convert(&build); (graph, vertex_map[v]) } fn single_edge() -> (Self, [Self::Vertex; 2], Self::Edge) { let (build, vertices, e) = AppendGraph::single_edge(); - let (graph, vertex_map, edge_map) = FrozenGraph::from_graph(&build); + let (graph, vertex_map, edge_map) = FrozenGraph::convert(&build); (graph, vertices.map(|v| vertex_map[v]), edge_map[e]) } fn disconnected() -> (Self, [Self::Vertex; 3]) { let (build, vertices) = AppendGraph::disconnected(); - let (graph, vertex_map, _) = FrozenGraph::from_graph(&build); + let (graph, vertex_map, _) = FrozenGraph::convert(&build); (graph, vertices.map(|v| vertex_map[v])) } fn loop_edge() -> (Self, Self::Vertex, Self::Edge) { let (build, v, e) = AppendGraph::loop_edge(); - let (graph, vertex_map, edge_map) = FrozenGraph::from_graph(&build); + let (graph, vertex_map, edge_map) = FrozenGraph::convert(&build); (graph, vertex_map[v], edge_map[e]) } fn multiple_edges() -> (Self, [Self::Vertex; 2], [Self::Edge; K]) { let (build, vertices, edges) = AppendGraph::multiple_edges(); - let (graph, vertex_map, edge_map) = FrozenGraph::from_graph(&build); + let (graph, vertex_map, edge_map) = FrozenGraph::convert(&build); ( graph, vertices.map(|v| vertex_map[v]), @@ -231,7 +231,7 @@ impl MakeTestGraph for FrozenGraph { fn two_edge_path() -> (Self, [Self::Vertex; 3], [Self::Edge; 2]) { let (build, vertices, edges) = AppendGraph::two_edge_path(); - let (graph, vertex_map, edge_map) = FrozenGraph::from_graph(&build); + let (graph, vertex_map, edge_map) = FrozenGraph::convert(&build); ( graph, vertices.map(|v| vertex_map[v]), @@ -241,7 +241,7 @@ impl MakeTestGraph for FrozenGraph { fn two_edge_path_with_loops() -> (Self, [Self::Vertex; 3], [Self::Edge; 4]) { let (build, vertices, edges) = AppendGraph::two_edge_path_with_loops(); - let (graph, vertex_map, edge_map) = FrozenGraph::from_graph(&build); + let (graph, vertex_map, edge_map) = FrozenGraph::convert(&build); ( graph, vertices.map(|v| vertex_map[v]), diff --git a/src/testing/graph_topology_from_graph_testing.rs b/src/testing/from_testing.rs similarity index 53% rename from src/testing/graph_topology_from_graph_testing.rs rename to src/testing/from_testing.rs index 82ef3e0..2253fd7 100644 --- a/src/testing/graph_topology_from_graph_testing.rs +++ b/src/testing/from_testing.rs @@ -1,16 +1,12 @@ -use std::fmt::Debug; - -use crate::testing::fixtures; use crate::testing::fixtures::MakeTestGraph; -use crate::traits::{FromGraph, GraphTopology}; +use crate::traits::GraphTopology; #[doc(hidden)] #[macro_export] -macro_rules! graph_topology_from_graph_tests { +macro_rules! from_tests { ($T:ty, $U:ty) => { - $crate::graph_topology_from_graph_tests!(@wrap $T, $U, + $crate::from_tests!(@wrap $T, $U, from, - from_graph, ); }; @@ -18,7 +14,7 @@ macro_rules! graph_topology_from_graph_tests { $( #[test] fn $name() { - $crate::testing::graph_topology_from_graph_testing::$name::<$T, $U>(); + $crate::testing::from_testing::$name::<$T, $U>(); } )* }; @@ -40,22 +36,3 @@ where actual.sort(); assert_eq!(actual, expected, "degree sequence should match"); } - -pub fn from_graph() -where - G::Vertex: Debug, - G::Edge: Debug, - H::Vertex: Debug, - H::Edge: Debug, -{ - let (source, vertices, edges, _) = H::standard(); - let (graph, vertex_map, edge_map) = G::from_graph(&source); - fixtures::assert_isomorphic( - &source, - &graph, - &vertices, - |v| vertex_map[v], - &edges, - |e| edge_map[e], - ); -} diff --git a/src/testing/graph_topology_addition_from_graph_testing.rs b/src/testing/graph_topology_addition_conversion_testing.rs similarity index 51% rename from src/testing/graph_topology_addition_from_graph_testing.rs rename to src/testing/graph_topology_addition_conversion_testing.rs index 9b5a5b4..171573d 100644 --- a/src/testing/graph_topology_addition_from_graph_testing.rs +++ b/src/testing/graph_topology_addition_conversion_testing.rs @@ -1,13 +1,13 @@ use crate::testing::fixtures; use crate::testing::fixtures::MakeTestGraph; -use crate::traits::{FromGraph, GraphTopologyAddition}; +use crate::traits::{GraphTopologyAddition, GraphTopologyConversion}; #[doc(hidden)] #[macro_export] -macro_rules! graph_topology_addition_from_graph_tests { +macro_rules! graph_topology_addition_conversion_tests { ($T:ty, $U:ty) => { - $crate::graph_topology_addition_from_graph_tests!(@wrap $T, $U, - from_graph_mutation_independent, + $crate::graph_topology_addition_conversion_tests!(@wrap $T, $U, + convert_mutation_independent, ); }; @@ -15,18 +15,18 @@ macro_rules! graph_topology_addition_from_graph_tests { $( #[test] fn $name() { - $crate::testing::graph_topology_addition_from_graph_testing::$name::<$T, $U>(); + $crate::testing::graph_topology_addition_conversion_testing::$name::<$T, $U>(); } )* }; } -pub fn from_graph_mutation_independent() +pub fn convert_mutation_independent() where - G: FromGraph + GraphTopologyAddition, + G: GraphTopologyConversion + GraphTopologyAddition, H: MakeTestGraph + GraphTopologyAddition, { let (mut source, vertices, _) = H::single_edge(); - let (mut graph, vertex_map, _) = G::from_graph(&source); + let (mut graph, vertex_map, _) = G::convert(&source); fixtures::assert_mutation_independent(&mut source, &mut graph, &vertices, |v| vertex_map[v]); } diff --git a/src/testing/graph_topology_conversion_testing.rs b/src/testing/graph_topology_conversion_testing.rs new file mode 100644 index 0000000..41f8de8 --- /dev/null +++ b/src/testing/graph_topology_conversion_testing.rs @@ -0,0 +1,43 @@ +use std::fmt::Debug; + +use crate::testing::fixtures; +use crate::testing::fixtures::MakeTestGraph; +use crate::traits::GraphTopologyConversion; + +#[doc(hidden)] +#[macro_export] +macro_rules! graph_topology_conversion_tests { + ($T:ty, $U:ty) => { + $crate::graph_topology_conversion_tests!(@wrap $T, $U, + convert, + ); + }; + + (@wrap $T:ty, $U:ty, $($name:ident),* $(,)?) => { + $( + #[test] + fn $name() { + $crate::testing::graph_topology_conversion_testing::$name::<$T, $U>(); + } + )* + }; +} + +pub fn convert() +where + G::Vertex: Debug, + G::Edge: Debug, + H::Vertex: Debug, + H::Edge: Debug, +{ + let (source, vertices, edges, _) = H::standard(); + let (graph, vertex_map, edge_map) = G::convert(&source); + fixtures::assert_isomorphic( + &source, + &graph, + &vertices, + |v| vertex_map[v], + &edges, + |e| edge_map[e], + ); +} diff --git a/src/traits.rs b/src/traits.rs index 45fce15..d491668 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -291,11 +291,11 @@ pub struct Incidence { // TODO-0.3.0: Provide and document a way to transform an ElementMap for source to an ElementMap for the copy. /// A trait for constructing an undirected graph topology by converting another graph /// implementation to this one. -pub trait FromGraph: GraphTopology { +pub trait GraphTopologyConversion: GraphTopology { /// Creates a new graph instance that is isomorphic to `source`. /// - /// Returns the copied graph instance and two mappings from the vertices and edges of `source` - /// to the corresponding vertices and edges of the returned graph. + /// Returns the converted graph instance and two mappings from the vertices and edges of + /// `source` to the corresponding vertices and edges of the returned graph. /// /// # Examples /// @@ -307,11 +307,11 @@ pub trait FromGraph: GraphTopology { /// let u = source.add_vertex(); /// let v = source.add_vertex(); /// let e = source.add_edge(u, v); - /// let (graph, vertex_map, edge_map) = FrozenGraph::from_graph(&source); + /// let (graph, vertex_map, edge_map) = FrozenGraph::convert(&source); /// /// assert!(graph.are_adjacent(vertex_map[u], vertex_map[v])); /// ``` - fn from_graph( + fn convert( source: &G, ) -> ( Self,