nodex_core/query/
traverse.rs1use crate::model::Graph;
2use std::collections::BTreeSet;
3
4pub fn find_backlinks(graph: &Graph, target_id: &str) -> Vec<BacklinkEntry> {
6 graph
7 .incoming_edges(target_id)
8 .iter()
9 .filter_map(|edge| {
10 let source = graph.node(&edge.source)?;
11 Some(BacklinkEntry {
12 id: source.id.clone(),
13 title: source.title.clone(),
14 relation: edge.relation.clone(),
15 location: edge.location.clone(),
16 })
17 })
18 .collect()
19}
20
21#[derive(Debug, serde::Serialize)]
22pub struct BacklinkEntry {
23 pub id: String,
24 pub title: String,
25 pub relation: String,
26 pub location: String,
27}
28
29pub fn find_chain(graph: &Graph, start_id: &str) -> Vec<ChainEntry> {
31 let mut chain = Vec::new();
32 let mut visited = BTreeSet::new();
33 let mut current_id = start_id.to_string();
34
35 loop {
36 if visited.contains(¤t_id) {
37 break; }
39 visited.insert(current_id.clone());
40
41 let Some(node) = graph.node(¤t_id) else {
42 break;
43 };
44
45 chain.push(ChainEntry {
46 id: node.id.clone(),
47 title: node.title.clone(),
48 status: node.status.to_string(),
49 });
50
51 match &node.superseded_by {
52 Some(next) => current_id = next.clone(),
53 None => break,
54 }
55 }
56
57 chain
58}
59
60#[derive(Debug, serde::Serialize)]
61pub struct ChainEntry {
62 pub id: String,
63 pub title: String,
64 pub status: String,
65}
66
67pub fn find_node_detail(graph: &Graph, id: &str) -> Option<NodeDetail> {
70 let node = graph.node(id)?;
71
72 let incoming: Vec<EdgeSummary> = graph
73 .incoming_edges(id)
74 .iter()
75 .map(|e| EdgeSummary {
76 node_id: e.source.clone(),
77 relation: e.relation.clone(),
78 confidence: e.confidence.to_string(),
79 })
80 .collect();
81
82 let outgoing: Vec<EdgeSummary> = graph
83 .outgoing_edges(id)
84 .iter()
85 .filter_map(|e| {
86 Some(EdgeSummary {
87 node_id: e.target.id()?.to_string(),
88 relation: e.relation.clone(),
89 confidence: e.confidence.to_string(),
90 })
91 })
92 .collect();
93
94 Some(NodeDetail {
95 node: node.clone(),
96 incoming,
97 outgoing,
98 })
99}
100
101#[derive(Debug, serde::Serialize)]
102pub struct NodeDetail {
103 pub node: crate::model::Node,
104 pub incoming: Vec<EdgeSummary>,
105 pub outgoing: Vec<EdgeSummary>,
106}
107
108#[derive(Debug, serde::Serialize)]
109pub struct EdgeSummary {
110 pub node_id: String,
111 pub relation: String,
112 pub confidence: String,
113}