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