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, Copy, PartialEq, Eq, Serialize, Deserialize)]
218#[serde(rename_all = "snake_case")]
219pub enum EdgeKind {
220 Calls,
221 Imports,
222 Uses,
223 Extends,
224 Implements,
225 Returns,
226 Parameter,
227 Field,
228 Contains,
229}
230
231impl EdgeKind {
232 pub fn as_str(&self) -> &'static str {
233 match self {
234 EdgeKind::Calls => "calls",
235 EdgeKind::Imports => "imports",
236 EdgeKind::Uses => "uses",
237 EdgeKind::Extends => "extends",
238 EdgeKind::Implements => "implements",
239 EdgeKind::Returns => "returns",
240 EdgeKind::Parameter => "parameter",
241 EdgeKind::Field => "field",
242 EdgeKind::Contains => "contains",
243 }
244 }
245}
246
247impl FromStr for EdgeKind {
248 type Err = ();
249 fn from_str(s: &str) -> Result<Self, Self::Err> {
250 match s {
251 "calls" => Ok(EdgeKind::Calls),
252 "imports" => Ok(EdgeKind::Imports),
253 "uses" => Ok(EdgeKind::Uses),
254 "extends" => Ok(EdgeKind::Extends),
255 "implements" => Ok(EdgeKind::Implements),
256 "returns" => Ok(EdgeKind::Returns),
257 "parameter" => Ok(EdgeKind::Parameter),
258 "field" => Ok(EdgeKind::Field),
259 "contains" => Ok(EdgeKind::Contains),
260 _ => Err(()),
261 }
262 }
263}
264
265#[derive(Debug, Clone, Serialize, Deserialize)]
267pub struct Edge {
268 pub source_id: String,
270 pub target_id: Option<String>,
272 pub target_name: String,
274 pub kind: EdgeKind,
276 pub line: Option<u32>,
278 pub col: Option<u32>,
280 pub context: Option<String>,
282}
283
284#[derive(Debug, Clone, Serialize, Deserialize)]
286pub struct ModuleInfo {
287 pub file_path: String,
288 pub module_name: Option<String>,
289 pub exports: Vec<String>,
290 pub imports: Vec<ImportInfo>,
291}
292
293#[derive(Debug, Clone, Serialize, Deserialize)]
295pub struct ImportInfo {
296 pub from: String,
297 pub names: Vec<String>,
298 pub alias: Option<String>,
299}
300
301#[derive(Debug, Clone)]
303pub struct ParseResult {
304 #[allow(dead_code)]
305 pub file_path: String,
306 pub language: String,
307 pub symbols: Vec<Symbol>,
308 pub edges: Vec<Edge>,
309 pub module: Option<ModuleInfo>,
310}
311
312#[derive(Debug, Clone, Serialize, Deserialize)]
314pub struct CodebaseStats {
315 pub files: i64,
316 pub symbols: i64,
317 pub edges: i64,
318 pub functions: i64,
319 pub structs: i64,
320 pub enums: i64,
321 pub traits: i64,
322}