ucp_codegraph/programmatic/
graph.rs1use std::sync::Arc;
2
3use anyhow::Result;
4use ucm_core::{BlockId, Document};
5
6use crate::{build_code_graph, CodeGraphBuildInput};
7
8use super::{
9 query,
10 session::CodeGraphNavigatorSession,
11 types::{CodeGraphFindQuery, CodeGraphNodeSummary, CodeGraphPathResult},
12};
13
14#[derive(Debug, Clone)]
15pub struct CodeGraphNavigator {
16 document: Arc<Document>,
17 graph: ucp_graph::GraphNavigator,
18}
19
20impl CodeGraphNavigator {
21 pub fn new(document: Document) -> Self {
22 let graph = ucp_graph::GraphNavigator::from_document(document.clone());
23 Self {
24 document: Arc::new(document),
25 graph,
26 }
27 }
28
29 pub fn build(input: &CodeGraphBuildInput) -> Result<Self> {
30 let result = build_code_graph(input)?;
31 Ok(Self::new(result.document))
32 }
33
34 pub fn document(&self) -> &Document {
35 self.document.as_ref()
36 }
37
38 pub fn graph(&self) -> &ucp_graph::GraphNavigator {
39 &self.graph
40 }
41
42 pub fn session(&self) -> CodeGraphNavigatorSession {
43 CodeGraphNavigatorSession::new(self.clone())
44 }
45
46 pub fn resolve_selector(&self, selector: &str) -> Option<BlockId> {
47 crate::resolve_codegraph_selector(self.document(), selector)
48 }
49
50 pub fn describe_node(&self, block_id: BlockId) -> Option<CodeGraphNodeSummary> {
51 query::describe_node(self.document(), block_id)
52 }
53
54 pub fn find_nodes(&self, query: &CodeGraphFindQuery) -> Result<Vec<CodeGraphNodeSummary>> {
55 query::find_nodes(self.document(), query)
56 }
57
58 pub fn path_between(
59 &self,
60 start: BlockId,
61 end: BlockId,
62 max_hops: usize,
63 ) -> Option<CodeGraphPathResult> {
64 query::path_between(self.document(), start, end, max_hops)
65 }
66
67 pub(crate) fn resolve_required(&self, selector: &str) -> Result<BlockId> {
68 query::resolve_required(self.document(), selector)
69 }
70}