#[cfg(feature = "hgraph")]
use crate::hgraph::h_graph::HeterogeneousGraph;
#[cfg(feature = "hgraph")]
use std::hash::Hash;
#[cfg(feature = "hgraph")]
#[derive(Debug)]
pub enum GraphConversionError {
EdgeAdditionError {
from: usize,
to: usize,
message: String,
},
}
#[cfg(feature = "hgraph")]
impl std::fmt::Display for GraphConversionError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
GraphConversionError::EdgeAdditionError { from, to, message } => {
write!(f, "Failed to add edge from {} to {}: {}", from, to, message)
}
}
}
}
#[cfg(feature = "hgraph")]
impl std::error::Error for GraphConversionError {}
#[cfg(feature = "hgraph")]
pub type Result<T> = std::result::Result<T, GraphConversionError>;
#[cfg(feature = "hgraph")]
pub trait GraphConversion<W, N, E>
where
W: Copy + PartialEq + Default + std::fmt::Debug,
N: Clone + Eq + Hash + std::fmt::Debug + crate::hgraph::h_node::NodeType,
E: Clone + std::fmt::Debug + Default + crate::hgraph::h_edge::EdgeType,
{
fn convert_to<N2, E2>(&self) -> Result<HeterogeneousGraph<W, N2, E2>>
where
W: Copy + PartialEq + Default + std::fmt::Debug,
N2: Clone + Eq + Hash + std::fmt::Debug + Default + crate::hgraph::h_node::NodeType,
E2: Clone + std::fmt::Debug + Default + crate::hgraph::h_edge::EdgeType;
fn to_string_graph(&self) -> Result<HeterogeneousGraph<W, String, String>>
where
W: Copy + PartialEq + Default + std::fmt::Debug,
N: crate::hgraph::h_node::NodeType,
E: crate::hgraph::h_edge::EdgeType;
}
#[cfg(feature = "hgraph")]
impl<W, N, E> GraphConversion<W, N, E> for HeterogeneousGraph<W, N, E>
where
W: Copy + PartialEq + Default + std::fmt::Debug,
N: Clone + Eq + Hash + std::fmt::Debug + crate::hgraph::h_node::NodeType,
E: Clone + std::fmt::Debug + Default + crate::hgraph::h_edge::EdgeType,
{
fn convert_to<N2, E2>(&self) -> Result<HeterogeneousGraph<W, N2, E2>>
where
W: Copy + PartialEq + Default + std::fmt::Debug,
N2: Clone + Eq + Hash + std::fmt::Debug + Default + crate::hgraph::h_node::NodeType,
E2: Clone + std::fmt::Debug + Default + crate::hgraph::h_edge::EdgeType,
{
let mut new_graph = HeterogeneousGraph::<W, N2, E2>::new(self.directed);
for (_id, node) in self.nodes.iter() {
let new_id = new_graph.add_node(N2::default());
for (key, value) in &node.attributes {
new_graph.set_node_attribute(new_id, key.clone(), value.clone());
}
}
for (from, to, weight, _edge_data) in self.get_all_edges() {
new_graph
.add_edge(from, to, weight, E2::default())
.map_err(|e| GraphConversionError::EdgeAdditionError {
from,
to,
message: e.to_string(),
})?;
if let Some(attrs) = self.get_all_edge_attributes(from, to) {
for (key, value) in attrs {
new_graph.set_edge_attribute(from, key.clone(), value.clone());
}
}
}
Ok(new_graph)
}
fn to_string_graph(&self) -> Result<HeterogeneousGraph<W, String, String>>
where
W: Copy + PartialEq + Default + std::fmt::Debug,
N: crate::hgraph::h_node::NodeType,
E: crate::hgraph::h_edge::EdgeType,
{
let mut new_graph = HeterogeneousGraph::<W, String, String>::new(self.directed);
for (_id, node) in self.nodes.iter() {
let new_id = new_graph.add_node(node.data.as_string());
for (key, value) in &node.attributes {
new_graph.set_node_attribute(new_id, key.clone(), value.clone());
}
}
for (from, to, weight, edge_data) in self.get_all_edges() {
new_graph
.add_edge(from, to, weight, edge_data.as_string())
.map_err(|e| GraphConversionError::EdgeAdditionError {
from,
to,
message: e.to_string(),
})?;
if let Some(attrs) = self.get_all_edge_attributes(from, to) {
for (key, value) in attrs {
new_graph.set_edge_attribute(from, key.clone(), value.clone());
}
}
}
Ok(new_graph)
}
}