use gryf::core::{
base::NeighborReference,
id::{IdType, IntegerIdType},
marker::{Directed, Direction, Undirected},
GraphBase, GraphRef, Neighbors, VertexSet,
};
use crate::error::Result;
use crate::graph::GraphDataBuilder;
pub fn from_gryf<V, E, G>(
graph: &gryf::Graph<V, E, Undirected, G>,
) -> Result<crate::graph::GraphData>
where
E: Into<f64> + Copy,
G: GraphBase<VertexId: IntegerIdType, EdgeType = Undirected>
+ Neighbors
+ VertexSet
+ GraphRef<V, E>,
{
let n = graph.vertex_count();
let mut builder = GraphDataBuilder::new(n);
for vertex_id in graph.vertices_by_id() {
let u = vertex_id.as_usize();
for neighbor in graph.neighbors_undirected(vertex_id) {
let v = neighbor.id().as_ref().as_usize();
if v < u {
continue;
}
let edge_ref = neighbor.edge();
let weight: f64 = graph
.edge(edge_ref.as_ref())
.map(|e| (*e).into())
.unwrap_or(1.0);
if !(weight.is_finite() && weight >= 0.0) {
return Err(crate::error::LeidenError::InvalidEdgeWeight { weight });
}
builder.add_edge(u, v, weight)?;
}
}
builder.build()
}
pub fn from_gryf_directed<V, E, G>(
graph: &gryf::Graph<V, E, Directed, G>,
) -> Result<crate::graph::GraphData>
where
E: Into<f64> + Copy,
G: GraphBase<VertexId: IntegerIdType, EdgeType = Directed>
+ Neighbors
+ VertexSet
+ GraphRef<V, E>,
{
let n = graph.vertex_count();
let mut builder = GraphDataBuilder::new(n).directed();
for vertex_id in graph.vertices_by_id() {
let u = vertex_id.as_usize();
for neighbor in graph.neighbors_directed(vertex_id, Direction::Outgoing) {
let v = neighbor.id().as_ref().as_usize();
let edge_ref = neighbor.edge();
let weight: f64 = graph
.edge(edge_ref.as_ref())
.map(|e| (*e).into())
.unwrap_or(1.0);
if !(weight.is_finite() && weight >= 0.0) {
return Err(crate::error::LeidenError::InvalidEdgeWeight { weight });
}
builder.add_edge(u, v, weight)?;
}
}
builder.build()
}