codebank/parser/mod.rs
1pub mod formatter;
2mod lang;
3mod units;
4
5use crate::Result;
6use std::path::{Path, PathBuf};
7
8pub use formatter::Formatter;
9pub use lang::{CppParser, GoParser, PythonParser, RustParser, TypeScriptParser};
10
11/// Represents visibility levels for code elements.
12///
13/// This enum is used to track the visibility of various code elements
14/// such as functions, structs, and modules.
15///
16/// # Examples
17///
18/// ```
19/// use codebank::Visibility;
20///
21/// // Public visibility
22/// let vis = Visibility::Public;
23/// assert!(matches!(vis, Visibility::Public));
24///
25/// // Private visibility
26/// let vis = Visibility::Private;
27/// assert!(matches!(vis, Visibility::Private));
28///
29/// // Crate visibility
30/// let vis = Visibility::Crate;
31/// assert!(matches!(vis, Visibility::Crate));
32///
33/// // Restricted visibility
34/// let vis = Visibility::Restricted("super::module".to_string());
35/// assert!(matches!(vis, Visibility::Restricted(_)));
36/// ```
37#[derive(Debug, Clone, PartialEq, Eq, Default)]
38pub enum Visibility {
39 /// Public visibility (accessible from outside the module)
40 #[default]
41 Public,
42
43 /// Private visibility (accessible only within the module)
44 Private,
45
46 /// Protected visibility (accessible within the module and its descendants)
47 Protected,
48
49 /// Crate visibility (accessible within the crate only)
50 Crate,
51
52 /// Visibility restricted to a specific path
53 Restricted(String),
54}
55
56/// The language type supported by the parser.
57///
58/// # Examples
59///
60/// ```
61/// use codebank::LanguageType;
62///
63/// // Check Rust files
64/// assert!(matches!(LanguageType::Rust, LanguageType::Rust));
65///
66/// // Check Python files
67/// assert!(matches!(LanguageType::Python, LanguageType::Python));
68///
69/// // Check TypeScript files
70/// assert!(matches!(LanguageType::TypeScript, LanguageType::TypeScript));
71///
72/// // Check C files
73/// assert!(matches!(LanguageType::Cpp, LanguageType::Cpp));
74///
75/// // Check Go files
76/// assert!(matches!(LanguageType::Go, LanguageType::Go));
77///
78/// // Handle unknown types
79/// assert!(matches!(LanguageType::Unknown, LanguageType::Unknown));
80/// ```
81#[derive(Debug, Clone, Copy, PartialEq, Eq)]
82pub enum LanguageType {
83 /// Rust language
84 Rust,
85 /// Python language
86 Python,
87 /// TypeScript language
88 TypeScript,
89 /// C/C++ language
90 Cpp,
91 /// Go language
92 Go,
93 /// Unknown language (used for unsupported extensions)
94 Unknown,
95}
96
97/// Trait for language-specific parsers.
98///
99/// This trait is implemented by parsers for different programming languages
100/// to provide consistent parsing behavior.
101///
102/// # Examples
103///
104/// ```
105/// use codebank::{LanguageParser, FileUnit, Result};
106/// use std::path::{Path, PathBuf};
107///
108/// struct MyParser;
109///
110/// impl LanguageParser for MyParser {
111/// fn parse_file(&mut self, file_path: &Path) -> Result<FileUnit> {
112/// // Simple implementation that creates an empty FileUnit
113/// Ok(FileUnit::new(file_path.to_path_buf()))
114/// }
115/// }
116///
117/// # fn main() -> Result<()> {
118/// let mut parser = MyParser;
119/// let file_unit = parser.parse_file(Path::new("example.rs"))?;
120/// assert_eq!(file_unit.path, PathBuf::from("example.rs"));
121/// # Ok(())
122/// # }
123/// ```
124pub trait LanguageParser {
125 /// Parse a file into a FileUnit
126 fn parse_file(&mut self, file_path: &Path) -> Result<FileUnit>;
127}
128
129/// Represents a file in the code.
130///
131/// This struct contains all the parsed information about a source code file,
132/// including its structure, contents, and metadata.
133///
134/// # Examples
135///
136/// ```
137/// use codebank::{FileUnit, Visibility, FunctionUnit};
138/// use std::path::PathBuf;
139///
140/// // Create a new file unit
141/// let mut file = FileUnit::new(PathBuf::from("example.rs"));
142///
143/// // Add documentation
144/// file.doc = Some("Example file documentation".to_string());
145///
146/// // Add a function
147/// let function = FunctionUnit {
148/// name: "example_function".to_string(),
149/// visibility: Visibility::Public,
150/// doc: Some("Function documentation".to_string()),
151/// signature: Some("fn example_function()".to_string()),
152/// body: Some("{ println!(\"Hello\"); }".to_string()),
153/// source: Some("fn example_function() { println!(\"Hello\"); }".to_string()),
154/// attributes: vec![],
155/// };
156/// file.functions.push(function);
157///
158/// assert_eq!(file.path, PathBuf::from("example.rs"));
159/// assert!(file.doc.is_some());
160/// assert!(!file.functions.is_empty());
161/// ```
162#[derive(Debug, Default)]
163pub struct FileUnit {
164 /// The path to the file
165 pub path: PathBuf,
166
167 /// File-level documentation
168 pub doc: Option<String>,
169
170 /// The declares in the file, e.g. imports, use statements, mod statements, c includes, python/js imports, etc.
171 pub declares: Vec<DeclareStatements>,
172
173 /// The modules contained in the file
174 pub modules: Vec<ModuleUnit>,
175
176 /// Top-level functions not in a module
177 pub functions: Vec<FunctionUnit>,
178
179 /// Top-level structs not in a module
180 pub structs: Vec<StructUnit>,
181
182 /// Top-level traits not in a module
183 pub traits: Vec<TraitUnit>,
184
185 /// Top-level implementation blocks
186 pub impls: Vec<ImplUnit>,
187
188 /// Source code of the entire file
189 pub source: Option<String>,
190}
191
192/// Represents declarations in source code.
193///
194/// This struct is used to store various types of declarations found in source files,
195/// such as imports, use statements, and module declarations.
196///
197/// # Examples
198///
199/// ```
200/// use codebank::{DeclareStatements, DeclareKind};
201///
202/// // Create an import declaration
203/// let import = DeclareStatements {
204/// source: "use std::io;".to_string(),
205/// kind: DeclareKind::Import,
206/// };
207/// assert!(matches!(import.kind, DeclareKind::Import));
208///
209/// // Create a module declaration
210/// let module = DeclareStatements {
211/// source: "mod example;".to_string(),
212/// kind: DeclareKind::Mod,
213/// };
214/// assert!(matches!(module.kind, DeclareKind::Mod));
215/// ```
216#[derive(Debug, Default)]
217pub struct DeclareStatements {
218 /// The source code of the declaration
219 pub source: String,
220 /// The kind of declaration
221 pub kind: DeclareKind,
222}
223
224/// The kind of declaration statement.
225///
226/// # Examples
227///
228/// ```
229/// use codebank::DeclareKind;
230///
231/// // Import declaration
232/// let kind = DeclareKind::Import;
233/// assert!(matches!(kind, DeclareKind::Import));
234///
235/// // Use declaration
236/// let kind = DeclareKind::Use;
237/// assert!(matches!(kind, DeclareKind::Use));
238///
239/// // Module declaration
240/// let kind = DeclareKind::Mod;
241/// assert!(matches!(kind, DeclareKind::Mod));
242///
243/// // Other declaration types
244/// let kind = DeclareKind::Other("macro_rules".to_string());
245/// assert!(matches!(kind, DeclareKind::Other(_)));
246/// ```
247#[derive(Debug, Default, PartialEq)]
248pub enum DeclareKind {
249 #[default]
250 Import,
251 Use,
252 Mod,
253 Other(String),
254}
255
256/// Represents a module in the code
257#[derive(Debug, Default)]
258pub struct ModuleUnit {
259 /// The name of the module
260 pub name: String,
261
262 /// Attributes applied to the module
263 pub attributes: Vec<String>,
264
265 /// The document for the module
266 pub doc: Option<String>,
267
268 /// The declares in the module, e.g. imports, use statements, mod statements, c includes, python/js imports, etc.
269 pub declares: Vec<DeclareStatements>,
270
271 /// The visibility of the module
272 pub visibility: Visibility,
273
274 /// Functions defined in the module
275 pub functions: Vec<FunctionUnit>,
276
277 /// Structs defined in the module
278 pub structs: Vec<StructUnit>,
279
280 /// Traits defined in the module
281 pub traits: Vec<TraitUnit>,
282
283 /// Implementation blocks defined in the module
284 pub impls: Vec<ImplUnit>,
285
286 /// Sub-modules defined in the module
287 pub submodules: Vec<ModuleUnit>,
288
289 /// Source code of the module declaration
290 pub source: Option<String>,
291}
292
293/// Represents a function or method in the code
294#[derive(Debug, Default, Clone)]
295pub struct FunctionUnit {
296 /// The name of the function
297 pub name: String,
298
299 /// Attributes applied to the function
300 pub attributes: Vec<String>,
301
302 /// The visibility of the function
303 pub visibility: Visibility,
304
305 /// The documentation for the function
306 pub doc: Option<String>,
307
308 /// The function signature (without body)
309 pub signature: Option<String>,
310
311 /// The function body
312 pub body: Option<String>,
313
314 /// The source code of the function
315 pub source: Option<String>,
316}
317
318/// Represents a struct or class in the code
319#[derive(Debug, Default)]
320pub struct StructUnit {
321 /// The name of the struct
322 pub name: String,
323
324 /// Attributes applied to the struct
325 pub attributes: Vec<String>,
326
327 /// The visibility of the struct
328 pub visibility: Visibility,
329
330 /// The documentation for the struct
331 pub doc: Option<String>,
332
333 /// struct head, e.g. struct Type, class Type, etc.
334 pub head: String,
335
336 /// The fields of the struct
337 pub fields: Vec<FieldUnit>,
338
339 /// The methods implemented for the struct
340 pub methods: Vec<FunctionUnit>,
341
342 /// The source code of the struct
343 pub source: Option<String>,
344}
345
346/// Represents a field in a struct
347#[derive(Debug, Default, Clone)]
348pub struct FieldUnit {
349 /// The name of the field
350 pub name: String,
351 /// documentation for the field
352 pub doc: Option<String>,
353 /// attributes applied to the field
354 pub attributes: Vec<String>,
355 /// the source code of the field
356 pub source: Option<String>,
357}
358
359/// Represents a trait or interface in the code
360#[derive(Debug, Default, Clone)]
361pub struct TraitUnit {
362 /// The name of the trait
363 pub name: String,
364
365 /// Attributes applied to the struct
366 pub attributes: Vec<String>,
367
368 /// The visibility of the trait
369 pub visibility: Visibility,
370
371 /// The documentation for the trait
372 pub doc: Option<String>,
373
374 /// The methods declared in the trait
375 pub methods: Vec<FunctionUnit>,
376
377 /// The source code of the trait
378 pub source: Option<String>,
379}
380
381/// Represents an implementation block in the code, not all languages need this
382#[derive(Debug, Default, Clone)]
383pub struct ImplUnit {
384 /// Attributes applied to the trait
385 pub attributes: Vec<String>,
386
387 /// The documentation for the implementation block
388 pub doc: Option<String>,
389
390 /// impl head, e.g. impl Trait for Type or impl Type
391 pub head: String,
392
393 /// The methods implemented in this block
394 pub methods: Vec<FunctionUnit>,
395
396 /// The source code of the implementation block
397 pub source: Option<String>,
398}
399
400impl Visibility {
401 pub fn as_str(&self, language: LanguageType) -> &str {
402 match (self, language) {
403 (Visibility::Public, LanguageType::Rust) => "pub",
404 (Visibility::Crate, LanguageType::Rust) => "pub(crate)",
405 (_, LanguageType::Rust) => "",
406 (_, LanguageType::Python) => "",
407 (_, LanguageType::TypeScript) => "",
408 (_, LanguageType::Cpp) => "",
409 (_, LanguageType::Go) => "",
410 (_, LanguageType::Unknown) => "",
411 }
412 }
413}
414
415impl LanguageType {
416 pub fn as_str(&self) -> &str {
417 match self {
418 LanguageType::Rust => "rust",
419 LanguageType::Python => "python",
420 LanguageType::TypeScript => "ts",
421 LanguageType::Cpp => "cpp",
422 LanguageType::Go => "go",
423 LanguageType::Unknown => "unknown",
424 }
425 }
426}