1use serde::{Deserialize, Serialize};
4use std::str::FromStr;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct FileRecord {
9 pub path: String,
10 pub content_hash: String,
11 pub size_bytes: i64,
12 pub language: Option<String>,
13 pub last_indexed: i64,
14}
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
18#[serde(rename_all = "snake_case")]
19pub enum SymbolKind {
20 Function,
21 Method,
22 Struct,
23 Enum,
24 Trait,
25 Impl,
26 Const,
27 Static,
28 Type,
29 Macro,
30 Module,
31 Field,
32 Variant,
33 Interface,
34 Class,
35 Variable,
36 Parameter,
37}
38
39impl SymbolKind {
40 pub fn as_str(&self) -> &'static str {
41 match self {
42 SymbolKind::Function => "function",
43 SymbolKind::Method => "method",
44 SymbolKind::Struct => "struct",
45 SymbolKind::Enum => "enum",
46 SymbolKind::Trait => "trait",
47 SymbolKind::Impl => "impl",
48 SymbolKind::Const => "const",
49 SymbolKind::Static => "static",
50 SymbolKind::Type => "type",
51 SymbolKind::Macro => "macro",
52 SymbolKind::Module => "module",
53 SymbolKind::Field => "field",
54 SymbolKind::Variant => "variant",
55 SymbolKind::Interface => "interface",
56 SymbolKind::Class => "class",
57 SymbolKind::Variable => "variable",
58 SymbolKind::Parameter => "parameter",
59 }
60 }
61}
62
63impl FromStr for SymbolKind {
64 type Err = ();
65 fn from_str(s: &str) -> Result<Self, Self::Err> {
66 match s {
67 "function" => Ok(SymbolKind::Function),
68 "method" => Ok(SymbolKind::Method),
69 "struct" => Ok(SymbolKind::Struct),
70 "enum" => Ok(SymbolKind::Enum),
71 "trait" => Ok(SymbolKind::Trait),
72 "impl" => Ok(SymbolKind::Impl),
73 "const" => Ok(SymbolKind::Const),
74 "static" => Ok(SymbolKind::Static),
75 "type" => Ok(SymbolKind::Type),
76 "macro" => Ok(SymbolKind::Macro),
77 "module" => Ok(SymbolKind::Module),
78 "field" => Ok(SymbolKind::Field),
79 "variant" => Ok(SymbolKind::Variant),
80 "interface" => Ok(SymbolKind::Interface),
81 "class" => Ok(SymbolKind::Class),
82 "variable" => Ok(SymbolKind::Variable),
83 "parameter" => Ok(SymbolKind::Parameter),
84 _ => Err(()),
85 }
86 }
87}
88
89#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
91#[serde(rename_all = "snake_case")]
92pub enum Visibility {
93 Public,
94 #[default]
95 Private,
96 Crate,
97 Super,
98 InPath,
99}
100
101impl Visibility {
102 pub fn as_str(&self) -> &'static str {
103 match self {
104 Visibility::Public => "public",
105 Visibility::Private => "private",
106 Visibility::Crate => "crate",
107 Visibility::Super => "super",
108 Visibility::InPath => "in_path",
109 }
110 }
111}
112
113impl FromStr for Visibility {
114 type Err = ();
115 fn from_str(s: &str) -> Result<Self, Self::Err> {
116 match s {
117 "public" | "pub" => Ok(Visibility::Public),
118 "crate" | "pub(crate)" => Ok(Visibility::Crate),
119 "super" | "pub(super)" => Ok(Visibility::Super),
120 "in_path" => Ok(Visibility::InPath),
121 _ => Ok(Visibility::Private),
122 }
123 }
124}
125
126#[derive(Debug, Clone, Serialize, Deserialize)]
128pub struct Symbol {
129 pub id: String,
131 pub file_path: String,
133 pub name: String,
135 pub qualified_name: Option<String>,
137 pub kind: SymbolKind,
139 pub visibility: Visibility,
141 pub signature: Option<String>,
143 pub brief: Option<String>,
145 pub docstring: Option<String>,
147 pub line_start: u32,
149 pub line_end: u32,
151 pub col_start: u32,
153 pub col_end: u32,
155 pub parent_id: Option<String>,
157 pub source: Option<String>,
159}
160
161impl Symbol {
162 pub fn make_id(file_path: &str, name: &str, parent: Option<&str>) -> String {
164 match parent {
165 Some(p) => format!("{}::{}::{}", file_path, p, name),
166 None => format!("{}::{}", file_path, name),
167 }
168 }
169
170 pub fn make_id_with_line(
172 file_path: &str,
173 name: &str,
174 parent: Option<&str>,
175 line: u32,
176 ) -> String {
177 match parent {
178 Some(p) => format!("{}::{}::{}@{}", file_path, p, name, line),
179 None => format!("{}::{}@{}", file_path, name, line),
180 }
181 }
182
183 pub fn to_embedding_text(&self) -> String {
185 let mut parts = vec![self.name.clone(), self.kind.as_str().to_string()];
186
187 if let Some(ref sig) = self.signature {
188 parts.push(sig.clone());
189 }
190
191 if let Some(ref brief) = self.brief {
192 parts.push(brief.clone());
193 }
194
195 match self.kind {
197 SymbolKind::Function | SymbolKind::Method => {
198 parts.push("function method procedure".into());
199 }
200 SymbolKind::Struct | SymbolKind::Class => {
201 parts.push("struct type data structure class".into());
202 }
203 SymbolKind::Enum => {
204 parts.push("enum enumeration variant".into());
205 }
206 SymbolKind::Trait | SymbolKind::Interface => {
207 parts.push("trait interface contract".into());
208 }
209 _ => {}
210 }
211
212 parts.join(" ")
213 }
214}
215
216#[derive(Debug, Clone, PartialEq, Eq)]
222pub struct Fingerprint {
223 pub symbol_id: String,
225 pub file_path: String,
227 pub minhash: Vec<u8>,
229 pub token_count: i64,
231}
232
233#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
235#[serde(rename_all = "snake_case")]
236pub enum EdgeKind {
237 Calls,
238 Imports,
239 Uses,
240 Extends,
241 Implements,
242 Returns,
243 Parameter,
244 Field,
245 Contains,
246}
247
248impl EdgeKind {
249 pub fn as_str(&self) -> &'static str {
250 match self {
251 EdgeKind::Calls => "calls",
252 EdgeKind::Imports => "imports",
253 EdgeKind::Uses => "uses",
254 EdgeKind::Extends => "extends",
255 EdgeKind::Implements => "implements",
256 EdgeKind::Returns => "returns",
257 EdgeKind::Parameter => "parameter",
258 EdgeKind::Field => "field",
259 EdgeKind::Contains => "contains",
260 }
261 }
262}
263
264impl FromStr for EdgeKind {
265 type Err = ();
266 fn from_str(s: &str) -> Result<Self, Self::Err> {
267 match s {
268 "calls" => Ok(EdgeKind::Calls),
269 "imports" => Ok(EdgeKind::Imports),
270 "uses" => Ok(EdgeKind::Uses),
271 "extends" => Ok(EdgeKind::Extends),
272 "implements" => Ok(EdgeKind::Implements),
273 "returns" => Ok(EdgeKind::Returns),
274 "parameter" => Ok(EdgeKind::Parameter),
275 "field" => Ok(EdgeKind::Field),
276 "contains" => Ok(EdgeKind::Contains),
277 _ => Err(()),
278 }
279 }
280}
281
282#[derive(Debug, Clone, Serialize, Deserialize)]
284pub struct Edge {
285 pub source_id: String,
287 pub target_id: Option<String>,
289 pub target_name: String,
291 pub kind: EdgeKind,
293 pub line: Option<u32>,
295 pub col: Option<u32>,
297 pub context: Option<String>,
299}
300
301#[derive(Debug, Clone, Serialize, Deserialize)]
303pub struct ModuleInfo {
304 pub file_path: String,
305 pub module_name: Option<String>,
306 pub exports: Vec<String>,
307 pub imports: Vec<ImportInfo>,
308}
309
310#[derive(Debug, Clone, Serialize, Deserialize)]
312pub struct ImportInfo {
313 pub from: String,
314 pub names: Vec<String>,
315 pub alias: Option<String>,
316}
317
318#[derive(Debug, Clone)]
320pub struct ParseResult {
321 #[allow(dead_code)]
322 pub file_path: String,
323 pub language: String,
324 pub symbols: Vec<Symbol>,
325 pub edges: Vec<Edge>,
326 pub module: Option<ModuleInfo>,
327}
328
329#[derive(Debug, Clone, Serialize, Deserialize)]
331pub struct CodebaseStats {
332 pub files: i64,
333 pub symbols: i64,
334 pub edges: i64,
335 pub functions: i64,
336 pub structs: i64,
337 pub enums: i64,
338 pub traits: i64,
339}