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}