#[cfg(feature = "hgraph")]
use crate::core::view::NodeId;
#[cfg(feature = "hgraph")]
use crate::hgraph::h_graph::HeterogeneousGraph;
#[cfg(feature = "hgraph")]
use std::hash::Hash;
#[cfg(feature = "hgraph")]
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
pub enum GraphConversionError {
#[error("Failed to add edge from {from} to {to}: {message}")]
EdgeAdditionError {
from: NodeId,
to: NodeId,
message: String,
},
}
#[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 {
let _ = new_graph.set_node_attribute(new_id, key.clone(), value.clone());
}
}
for (_, edge) in self.edges.iter() {
let (from, to) = (edge.from, edge.to);
let new_edge_id = new_graph
.add_edge(from, to, edge.weight, E2::default())
.map_err(|e| GraphConversionError::EdgeAdditionError {
from,
to,
message: e.to_string(),
})?;
for (key, value) in &edge.attributes {
let _ = new_graph.set_edge_attribute(new_edge_id, 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 {
let _ = new_graph.set_node_attribute(new_id, key.clone(), value.clone());
}
}
for (_, edge) in self.edges.iter() {
let (from, to) = (edge.from, edge.to);
let new_edge_id = new_graph
.add_edge(from, to, edge.weight, edge.data.as_string())
.map_err(|e| GraphConversionError::EdgeAdditionError {
from,
to,
message: e.to_string(),
})?;
for (key, value) in &edge.attributes {
let _ = new_graph.set_edge_attribute(new_edge_id, key.clone(), value.clone());
}
}
Ok(new_graph)
}
}