1pub mod cxx_bindings;
7
8use graphrust_core::{EdgeWeight, Graph, NodeId};
9
10pub use graphrust_algos::{
12 bfs_distances, bfs_predecessors, bfs_traverse, clustering_coefficient, component_count,
13 connected_components, dijkstra, dijkstra_path, dijkstra_with_predecessors, node_component_map,
14 pagerank, pagerank_converge, top_k_pagerank, triangle_count, triangles_per_node,
15};
16
17#[derive(Clone)]
19pub struct FFIGraph {
20 graph: Graph,
21}
22
23impl FFIGraph {
24 pub fn new(num_nodes: u32, is_directed: bool) -> Self {
26 FFIGraph {
27 graph: Graph::new(num_nodes, is_directed),
28 }
29 }
30
31 pub fn add_edge(&mut self, from: u32, to: u32, weight: f64) {
33 let from_id = NodeId::new(from);
34 let to_id = NodeId::new(to);
35 let edge_weight = if weight == 1.0 {
36 None
37 } else {
38 Some(EdgeWeight::new(weight))
39 };
40 self.graph.add_edge(from_id, to_id, edge_weight);
41 }
42
43 pub fn num_nodes(&self) -> u32 {
45 self.graph.num_nodes()
46 }
47
48 pub fn num_edges(&self) -> u32 {
50 self.graph.num_edges()
51 }
52
53 pub fn bfs_traverse_ffi(&self, start: u32) -> Vec<u32> {
55 let traversal = bfs_traverse(&self.graph, NodeId::new(start));
56 traversal.iter().map(|n| n.0).collect()
57 }
58
59 pub fn bfs_distances_ffi(&self, start: u32) -> Vec<u32> {
61 let distances = bfs_distances(&self.graph, NodeId::new(start));
62 let mut result = vec![u32::MAX; self.graph.num_nodes() as usize];
63 for (node, dist) in distances {
64 result[node.as_usize()] = dist;
65 }
66 result
67 }
68
69 pub fn dijkstra_ffi(&self, start: u32) -> Vec<f64> {
71 let distances = dijkstra(&self.graph, NodeId::new(start));
72 let mut result = vec![f64::INFINITY; self.graph.num_nodes() as usize];
73 for (node, dist) in distances {
74 result[node.as_usize()] = dist;
75 }
76 result
77 }
78
79 pub fn pagerank_ffi(&self, iterations: u32, damping_factor: f64) -> Vec<f64> {
81 pagerank(&self.graph, iterations, damping_factor)
82 }
83
84 pub fn triangle_count_ffi(&self) -> u64 {
86 triangle_count(&self.graph)
87 }
88
89 pub fn component_count_ffi(&self) -> u32 {
91 component_count(&self.graph) as u32
92 }
93
94 pub fn clustering_coefficient_ffi(&self) -> f64 {
96 clustering_coefficient(&self.graph)
97 }
98}
99
100pub fn create_graph_from_edges(
102 num_nodes: u32,
103 is_directed: bool,
104 edges: &[(u32, u32, f64)],
105) -> FFIGraph {
106 let mut graph = FFIGraph::new(num_nodes, is_directed);
107 for &(from, to, weight) in edges {
108 graph.add_edge(from, to, weight);
109 }
110 graph
111}
112
113#[cfg(test)]
114mod tests {
115 use super::*;
116
117 #[test]
118 fn test_ffi_graph_creation() {
119 let graph = FFIGraph::new(5, true);
120 assert_eq!(graph.num_nodes(), 5);
121 assert_eq!(graph.num_edges(), 0);
122 }
123
124 #[test]
125 fn test_ffi_graph_edges() {
126 let mut graph = FFIGraph::new(5, true);
127 graph.add_edge(0, 1, 1.0);
128 graph.add_edge(1, 2, 2.5);
129 assert_eq!(graph.num_edges(), 2);
130 }
131}