use crate::graph::v2::{GraphNodeKind, GraphSnapshot};
use std::collections::BTreeMap;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DirectoryDependency {
pub from: String,
pub to: String,
pub edge_count: usize,
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct GraphDirectoryDependencies {
pub edges: Vec<DirectoryDependency>,
}
pub fn directory_dependencies(snapshot: &GraphSnapshot) -> GraphDirectoryDependencies {
let directory_by_file = snapshot
.nodes
.iter()
.filter(|node| node.kind == GraphNodeKind::File)
.map(|node| (node.id.clone(), directory_of(&node.label)))
.collect::<BTreeMap<_, _>>();
let mut counts: BTreeMap<(String, String), usize> = BTreeMap::new();
for edge in &snapshot.edges {
if !edge.kind.is_dependency() {
continue;
}
let (Some(from_dir), Some(to_dir)) = (
directory_by_file.get(&edge.from),
directory_by_file.get(&edge.to),
) else {
continue;
};
if from_dir != to_dir {
*counts
.entry((from_dir.clone(), to_dir.clone()))
.or_insert(0) += 1;
}
}
let edges = counts
.into_iter()
.map(|((from, to), edge_count)| DirectoryDependency {
from,
to,
edge_count,
})
.collect();
GraphDirectoryDependencies { edges }
}
fn directory_of(label: &str) -> String {
match label.rfind('/') {
Some(index) => label[..index].to_string(),
None => ".".to_string(),
}
}