use anyhow::Result;
use magellan::{
CodeGraph, CondensationResult, CycleReport, DeadSymbol, PathEnumerationResult, SymbolInfo,
};
use super::json_types::{CondensationJson, PathEnumerationJson, SliceWrapper};
pub struct MagellanBridge {
graph: CodeGraph,
}
impl MagellanBridge {
pub fn open(db_path: &str) -> Result<Self> {
let graph = CodeGraph::open(db_path)?;
Ok(Self { graph })
}
pub fn graph(&self) -> &CodeGraph {
&self.graph
}
pub fn reachable_symbols(&self, symbol_id: &str) -> Result<Vec<SymbolInfo>> {
self.graph.reachable_symbols(symbol_id, None)
}
pub fn reverse_reachable_symbols(&self, symbol_id: &str) -> Result<Vec<SymbolInfo>> {
self.graph.reverse_reachable_symbols(symbol_id, None)
}
pub fn k_hop_callees(
&self,
symbol_name: &str,
depth: usize,
) -> Result<Vec<magellan::graph::navigator::DepthSymbol>> {
let nav = self.graph.navigator();
let resolved = nav.resolve(symbol_name)?;
if resolved.is_empty() {
anyhow::bail!("symbol '{}' not found", symbol_name);
}
nav.k_hop_callees(resolved[0].id, depth as u32)
}
pub fn k_hop_callers(
&self,
symbol_name: &str,
depth: usize,
) -> Result<Vec<magellan::graph::navigator::DepthSymbol>> {
let nav = self.graph.navigator();
let resolved = nav.resolve(symbol_name)?;
if resolved.is_empty() {
anyhow::bail!("symbol '{}' not found", symbol_name);
}
nav.k_hop_callers(resolved[0].id, depth as u32)
}
pub fn dead_symbols(&self, entry_symbol_id: &str) -> Result<Vec<DeadSymbol>> {
self.graph.dead_symbols(entry_symbol_id)
}
pub fn detect_cycles(&self) -> Result<CycleReport> {
self.graph.detect_cycles()
}
pub fn backward_slice(&self, symbol_id: &str) -> Result<SliceWrapper> {
let result = self.graph.backward_slice(symbol_id)?;
Ok((&result).into())
}
pub fn forward_slice(&self, symbol_id: &str) -> Result<SliceWrapper> {
let result = self.graph.forward_slice(symbol_id)?;
Ok((&result).into())
}
pub fn enumerate_paths(
&self,
start_symbol_id: &str,
end_symbol_id: Option<&str>,
max_depth: usize,
max_paths: usize,
) -> Result<PathEnumerationResult> {
self.graph
.enumerate_paths(start_symbol_id, end_symbol_id, max_depth, max_paths)
}
pub fn enumerate_paths_json(
&self,
start_symbol_id: &str,
end_symbol_id: Option<&str>,
max_depth: usize,
max_paths: usize,
) -> Result<PathEnumerationJson> {
let result =
self.graph
.enumerate_paths(start_symbol_id, end_symbol_id, max_depth, max_paths)?;
Ok((&result).into())
}
pub fn condense_call_graph(&self) -> Result<CondensationResult> {
self.graph.condense_call_graph()
}
pub fn condense_call_graph_json(&self) -> Result<CondensationJson> {
let result = self.graph.condense_call_graph()?;
Ok((&result).into())
}
}