Renamed FromGraph to GraphTopologyConversion to align with existing traits and separate from From trait
This commit is contained in:
+2
-2
@@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+5
-4
@@ -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<G: GraphTopologyAddition, H: GraphTopology>(
|
||||
/// [`GraphTopologyConversion`]: crate::traits::GraphTopologyConversion
|
||||
pub(crate) fn convert_to_addition<G: GraphTopologyAddition, H: GraphTopology>(
|
||||
source: &H,
|
||||
vertex_default: G::Vertex,
|
||||
mut on_edge: impl FnMut(H::Edge, G::Edge),
|
||||
|
||||
+15
-12
@@ -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<H: GraphTopology> From<&H> for AppendGraph {
|
||||
fn from(source: &H) -> Self {
|
||||
models::build_from_topology::<Self, _>(source, Vertex(usize::MAX), |_, _| {}).0
|
||||
}
|
||||
}
|
||||
|
||||
impl FromGraph for AppendGraph {
|
||||
fn from_graph<H: GraphTopology>(
|
||||
impl GraphTopologyConversion for AppendGraph {
|
||||
fn convert<H: GraphTopology>(
|
||||
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<H: GraphTopology> From<&H> for AppendGraph {
|
||||
fn from(source: &H) -> Self {
|
||||
models::convert_to_addition::<Self, _>(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)]
|
||||
|
||||
+12
-11
@@ -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<FrozenGraph> 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<G: GraphTopology> From<&G> for FrozenGraph {
|
||||
fn from(graph: &G) -> Self {
|
||||
Self::from_graph(graph).0
|
||||
}
|
||||
}
|
||||
|
||||
impl FromGraph for FrozenGraph {
|
||||
fn from_graph<G: GraphTopology>(
|
||||
impl GraphTopologyConversion for FrozenGraph {
|
||||
fn convert<G: GraphTopology>(
|
||||
source: &G,
|
||||
) -> (
|
||||
Self,
|
||||
@@ -253,6 +247,12 @@ impl FromGraph for FrozenGraph {
|
||||
}
|
||||
}
|
||||
|
||||
impl<G: GraphTopology> 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)]
|
||||
|
||||
+19
-18
@@ -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<H: GraphTopology> From<&H> for Graph {
|
||||
fn from(source: &H) -> Self {
|
||||
models::build_from_topology::<Self, _>(
|
||||
source,
|
||||
Vertex::new(usize::MAX, usize::MAX),
|
||||
|_, _| {},
|
||||
)
|
||||
.0
|
||||
}
|
||||
}
|
||||
|
||||
impl FromGraph for Graph {
|
||||
fn from_graph<H: GraphTopology>(
|
||||
impl GraphTopologyConversion for Graph {
|
||||
fn convert<H: GraphTopology>(
|
||||
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<H: GraphTopology> From<&H> for Graph {
|
||||
fn from(source: &H) -> Self {
|
||||
models::convert_to_addition::<Self, _>(
|
||||
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)]
|
||||
|
||||
+3
-2
@@ -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;
|
||||
|
||||
@@ -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<Incidence<Self::Vertex, Self::Edge>>; 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<const K: usize>() -> (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]),
|
||||
|
||||
@@ -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<G: FromGraph, H: MakeTestGraph>()
|
||||
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],
|
||||
);
|
||||
}
|
||||
+8
-8
@@ -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<G, H>()
|
||||
pub fn convert_mutation_independent<G, H>()
|
||||
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]);
|
||||
}
|
||||
@@ -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<G: GraphTopologyConversion, H: MakeTestGraph>()
|
||||
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],
|
||||
);
|
||||
}
|
||||
+5
-5
@@ -291,11 +291,11 @@ pub struct Incidence<V, E> {
|
||||
// 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<G: GraphTopology>(
|
||||
fn convert<G: GraphTopology>(
|
||||
source: &G,
|
||||
) -> (
|
||||
Self,
|
||||
|
||||
Reference in New Issue
Block a user