use crate::error::Result;
use crate::graph::Graph;
use crate::types::{Edge, Node, NodeId};
use std::collections::HashSet;
pub trait GraphView: Send + Sync {
fn get_all_nodes(&self) -> impl std::future::Future<Output = Result<Vec<Node>>> + Send;
fn get_all_edges(&self) -> impl std::future::Future<Output = Result<Vec<Edge>>> + Send;
}
impl GraphView for Graph {
async fn get_all_nodes(&self) -> Result<Vec<Node>> {
self.get_all_nodes().await
}
async fn get_all_edges(&self) -> Result<Vec<Edge>> {
self.get_all_edges().await
}
}
pub struct Subgraph<'a> {
graph: &'a Graph,
allowed_nodes: HashSet<NodeId>,
}
impl<'a> Subgraph<'a> {
pub fn new(graph: &'a Graph, allowed_nodes: HashSet<NodeId>) -> Self {
Self {
graph,
allowed_nodes,
}
}
pub fn from_nodes(graph: &'a Graph, nodes: &[Node]) -> Self {
let allowed_nodes = nodes.iter().map(|n| n.id).collect();
Self {
graph,
allowed_nodes,
}
}
pub fn inner(&self) -> &Graph {
self.graph
}
}
impl<'a> GraphView for Subgraph<'a> {
async fn get_all_nodes(&self) -> Result<Vec<Node>> {
let mut nodes = Vec::with_capacity(self.allowed_nodes.len());
for &id in &self.allowed_nodes {
match self.graph.get_node(id).await {
Ok(node) => nodes.push(node),
Err(_) => continue, }
}
Ok(nodes)
}
async fn get_all_edges(&self) -> Result<Vec<Edge>> {
let mut edges = Vec::new();
for &node_id in &self.allowed_nodes {
if let Ok(outgoing) = self.graph.get_outgoing_edges(node_id).await {
for edge in outgoing {
if self.allowed_nodes.contains(&edge.target) {
edges.push(edge);
}
}
}
}
Ok(edges)
}
}