init: archlens — architecture diagram generator
Some checks failed
CI / Check / Test (push) Failing after 1m24s

Hex arch + DDD, tree-sitter parsing, Mermaid/ASCII output.
Supports Rust + Python. 92 tests. CI, diff, --check for staleness detection.
This commit is contained in:
2026-06-16 16:13:04 +02:00
commit 35f27d00b0
106 changed files with 6744 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
use std::collections::HashSet;
use crate::{CodeElement, ModuleName, Relationship};
#[derive(Debug, Clone)]
pub struct CodeGraph {
elements: Vec<CodeElement>,
relationships: Vec<Relationship>,
}
impl Default for CodeGraph {
fn default() -> Self {
Self::new()
}
}
impl CodeGraph {
pub fn new() -> Self {
Self {
elements: Vec::new(),
relationships: Vec::new(),
}
}
pub fn add_element(&mut self, element: CodeElement) {
self.elements.push(element);
}
pub fn add_relationship(&mut self, relationship: Relationship) {
self.relationships.push(relationship);
}
pub fn elements(&self) -> &[CodeElement] {
&self.elements
}
pub fn relationships(&self) -> &[Relationship] {
&self.relationships
}
pub fn modules(&self) -> Vec<ModuleName> {
let mut seen = HashSet::new();
let mut modules = Vec::new();
for element in &self.elements {
if let Some(module) = element.module()
&& seen.insert(module.as_str().to_string())
{
modules.push(module.clone());
}
}
modules
}
pub fn subgraph_by_module(&self, module: &ModuleName) -> CodeGraph {
let filtered_elements: Vec<CodeElement> = self
.elements
.iter()
.filter(|e| e.module().is_some_and(|m| m == module))
.cloned()
.collect();
let element_names: HashSet<&str> = filtered_elements.iter().map(|e| e.name()).collect();
let filtered_relationships: Vec<Relationship> = self
.relationships
.iter()
.filter(|r| element_names.contains(r.source()) && element_names.contains(r.target()))
.cloned()
.collect();
CodeGraph {
elements: filtered_elements,
relationships: filtered_relationships,
}
}
}