use super::{EdgeType, GraphEdge, GraphNode};
use crate::config::manifest::RivoxManifest;
use anyhow::Result;
use petgraph::graph::{DiGraph, NodeIndex};
use std::collections::HashMap;
pub struct UnifiedGraph {
pub graph: DiGraph<GraphNode, GraphEdge>,
pub node_map: HashMap<String, NodeIndex>,
}
impl UnifiedGraph {
pub fn new() -> Self {
Self {
graph: DiGraph::new(),
node_map: HashMap::new(),
}
}
}
impl Default for UnifiedGraph {
fn default() -> Self {
Self::new()
}
}
impl UnifiedGraph {
pub fn add_nodes(&mut self, nodes: Vec<GraphNode>) {
for node in nodes {
let key = format!(
"{}:{}:{}",
node.ecosystem, node.package_name, node.resolved_version
);
if !self.node_map.contains_key(&key) {
let idx = self.graph.add_node(node);
self.node_map.insert(key, idx);
}
}
}
pub fn apply_cross_refs(&mut self, manifest: &RivoxManifest) -> Result<()> {
for cr in &manifest.cross_refs {
let from_key = &cr.consumer;
let to_key = &cr.dependency;
if let (Some(&from_idx), Some(&to_idx)) =
(self.node_map.get(from_key), self.node_map.get(to_key))
{
let edge = GraphEdge {
from_node: from_key.clone(),
to_node: to_key.clone(),
edge_type: EdgeType::UserDeclaredCrossRef,
};
self.graph.add_edge(from_idx, to_idx, edge);
}
}
Ok(())
}
}