1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
4pub struct Symbol {
5 pub symbol_id: String,
6 pub file_id: String,
7 pub path: String,
8 pub language: String,
9 pub name: String,
10 pub kind: String,
11 pub signature: Option<String>,
12 pub doc_comment: Option<String>,
13 pub visibility: Option<String>,
14 pub parent_symbol_id: Option<String>,
15 pub start_line: usize,
16 pub start_column: usize,
17 pub end_line: usize,
18 pub end_column: usize,
19 pub start_byte: usize,
20 pub end_byte: usize,
21 pub body_start_line: Option<usize>,
22 pub body_start_column: Option<usize>,
23 pub body_end_line: Option<usize>,
24 pub body_end_column: Option<usize>,
25 pub body_start_byte: Option<usize>,
26 pub body_end_byte: Option<usize>,
27 pub body_hash: Option<String>,
28 pub semantic_group: Option<String>,
29 pub is_test: bool,
30 pub test_container: bool,
31}
32
33impl Symbol {
34 pub fn hidden_body_line_count(&self) -> Option<usize> {
36 match (self.body_start_line, self.body_end_line) {
37 (Some(start), Some(end)) if end >= start => Some(end - start + 1),
38 _ => None,
39 }
40 }
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
44pub struct FileFact {
45 pub file_id: String,
46 pub path: String,
47 pub language: String,
48 pub content_hash: String,
49 pub content_bytes: i64,
50 pub line_count: Option<i64>,
51 pub indexed_at: String,
52}
53
54#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
55pub struct ReferenceSite {
56 pub from_symbol_name: String,
57 pub from_symbol_id: String,
58 pub to_symbol_name: String,
59 pub kind: String,
60 pub path: String,
61 pub start_line: Option<usize>,
62 pub start_column: Option<usize>,
63 #[serde(default, skip_serializing_if = "Option::is_none")]
64 pub occurrences: Option<usize>,
65 #[serde(default, skip_serializing_if = "Option::is_none")]
67 pub target: Option<String>,
68 #[serde(skip)]
70 pub enclosing_symbol_name: Option<String>,
71}
72
73pub(crate) fn has_generated_lambda_name(name: &str) -> bool {
74 name.strip_prefix("lambda_")
75 .is_some_and(|line| !line.is_empty() && line.bytes().all(|byte| byte.is_ascii_digit()))
76}
77
78pub(crate) fn is_generated_lambda_name(
79 name: &str,
80 language: &str,
81 kind: &str,
82 signature: Option<&str>,
83) -> bool {
84 has_generated_lambda_name(name)
85 && language == "python"
86 && kind == "function"
87 && signature.is_some_and(|signature| signature.starts_with("lambda"))
88}
89
90#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
91pub struct StructuralFact {
92 pub structural_fact_id: String,
93 pub path: String,
94 pub language: String,
95 pub pattern_id: String,
96 pub capture_name: String,
97 pub node_kind: String,
98 pub key: Option<String>,
99 pub metadata: Option<serde_json::Value>,
100 pub containing_symbol_name: Option<String>,
101 pub start_line: usize,
102 pub end_line: usize,
103 pub confidence: f64,
104}
105
106#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
107pub struct LiteralFact {
108 pub literal_id: String,
109 pub path: String,
110 pub literal_text: String,
111 pub kind: String,
112 pub carrier: Option<String>,
113 pub start_line: usize,
114 pub containing_symbol_name: Option<String>,
115}
116
117#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
118pub struct TypeFact {
119 pub type_fact_id: String,
120 pub symbol_id: String,
121 pub language: String,
122 pub resolved_type: String,
123 pub generic_params: Option<String>,
124}
125
126#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
127pub struct ContextSlice {
128 pub target_symbol: Symbol,
129 pub target_body: String,
130 pub callee_signatures: Vec<String>,
131 pub related_types: Vec<String>,
132 pub related_tests: Vec<Symbol>,
133}
134
135#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
138pub struct SymbolSearchResult {
139 pub symbol: Symbol,
140 pub score: f64,
141 pub snippet: Option<String>,
142 #[serde(default, skip_serializing_if = "Option::is_none")]
143 pub explain: Option<SearchExplain>,
144}
145
146#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
151pub struct SearchExplain {
152 pub bm25: Option<f64>,
153 pub branches: Vec<String>,
154 pub name_tier: String,
155 pub name_strength: u32,
156 pub terms: Vec<(String, String, f64)>,
157 pub term_score: f64,
158 #[serde(default)]
159 pub field_diversity_bonus: f64,
160 pub name_bonus: f64,
161 pub kind_prior: f64,
162 pub path_role: f64,
163 pub documentation: f64,
164 pub test_intent: f64,
165 #[serde(default)]
166 pub nested: f64,
167 pub word_weights: Vec<(String, f64)>,
168 pub candidates: usize,
169 pub rerank_us: u128,
170}
171
172#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
173pub struct BlastRadiusResult {
174 pub seed_type: String,
175 pub seeds: Vec<String>,
176 pub likely_tests: Vec<TestTarget>,
177 pub impacted_symbols: Vec<ImpactedSymbol>,
178 pub likely_tests_truncated: bool,
179 pub impacted_symbols_truncated: bool,
180 #[serde(default)]
181 pub traversal_ceiling_reached: bool,
182 pub test_file_ceiling_reached: bool,
183 #[serde(default)]
185 pub limit_at_maximum: bool,
186 #[serde(default)]
188 pub likely_tests_found: usize,
189 #[serde(default)]
191 pub impacted_symbols_found: usize,
192}
193
194#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
195pub struct TestTarget {
196 pub name: String,
197 pub path: String,
198 pub line: usize,
199 pub reason: String,
200}
201
202#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
203pub struct ImpactedSymbol {
204 pub name: String,
205 pub kind: String,
206 pub path: String,
207 pub line: usize,
208 pub depth: usize,
209 #[serde(skip)]
211 pub enclosing_symbol_name: Option<String>,
212}