herolib_code/parser/
types.rs

1//! Type definitions for parsed Rust code structures.
2//!
3//! This module defines the data structures used to represent parsed Rust code elements
4//! including enumerators, structs, methods, and their associated documentation.
5
6use serde::{Deserialize, Serialize};
7
8/// Represents a parsed Rust codebase containing all discovered code elements.
9#[derive(Debug, Clone, Default, Serialize, Deserialize)]
10pub struct CodeBase {
11    /// All discovered enumerators in the codebase.
12    pub enums: Vec<EnumInfo>,
13    /// All discovered structs in the codebase.
14    pub structs: Vec<StructInfo>,
15    /// Source files that were parsed.
16    pub files: Vec<FileInfo>,
17}
18
19impl CodeBase {
20    /// Creates a new empty CodeBase.
21    pub fn new() -> Self {
22        Self::default()
23    }
24
25    /// Merges another CodeBase into this one.
26    pub fn merge(&mut self, other: CodeBase) {
27        self.enums.extend(other.enums);
28        self.structs.extend(other.structs);
29        self.files.extend(other.files);
30    }
31
32    /// Returns the total number of code elements.
33    pub fn total_elements(&self) -> usize {
34        self.enums.len() + self.structs.len()
35    }
36}
37
38/// Information about a parsed source file.
39#[derive(Debug, Clone, Serialize, Deserialize)]
40pub struct FileInfo {
41    /// The file path relative to the root directory.
42    pub path: String,
43    /// Number of enums found in this file.
44    pub enum_count: usize,
45    /// Number of structs found in this file.
46    pub struct_count: usize,
47}
48
49/// Represents a parsed Rust enum with its variants and documentation.
50#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct EnumInfo {
52    /// The name of the enum.
53    pub name: String,
54    /// Documentation comment for the enum.
55    pub doc_comment: Option<String>,
56    /// The file where this enum is defined.
57    pub file_path: String,
58    /// Line number where the enum starts.
59    pub line_number: usize,
60    /// Visibility of the enum (pub, pub(crate), etc.).
61    pub visibility: Visibility,
62    /// Generic parameters if any.
63    pub generics: Vec<String>,
64    /// Derive macros applied to this enum.
65    pub derives: Vec<String>,
66    /// Other attributes on the enum.
67    pub attributes: Vec<String>,
68    /// Variants of the enum.
69    pub variants: Vec<EnumVariant>,
70}
71
72/// Represents a single variant of an enum.
73#[derive(Debug, Clone, Serialize, Deserialize)]
74pub struct EnumVariant {
75    /// The name of the variant.
76    pub name: String,
77    /// Documentation comment for the variant.
78    pub doc_comment: Option<String>,
79    /// Fields of the variant (for tuple or struct variants).
80    pub fields: Vec<FieldInfo>,
81    /// Discriminant value if specified (e.g., `Variant = 5`).
82    pub discriminant: Option<String>,
83}
84
85/// Represents a parsed Rust struct with its fields and documentation.
86#[derive(Debug, Clone, Serialize, Deserialize)]
87pub struct StructInfo {
88    /// The name of the struct.
89    pub name: String,
90    /// Documentation comment for the struct.
91    pub doc_comment: Option<String>,
92    /// The file where this struct is defined.
93    pub file_path: String,
94    /// Line number where the struct starts.
95    pub line_number: usize,
96    /// Visibility of the struct.
97    pub visibility: Visibility,
98    /// Generic parameters if any.
99    pub generics: Vec<String>,
100    /// Derive macros applied to this struct.
101    pub derives: Vec<String>,
102    /// Other attributes on the struct.
103    pub attributes: Vec<String>,
104    /// Fields of the struct.
105    pub fields: Vec<FieldInfo>,
106    /// Methods implemented on this struct.
107    pub methods: Vec<MethodInfo>,
108}
109
110/// Represents a field in a struct or enum variant.
111#[derive(Debug, Clone, Serialize, Deserialize)]
112pub struct FieldInfo {
113    /// The name of the field (None for tuple struct fields).
114    pub name: Option<String>,
115    /// The type of the field as a string.
116    pub ty: String,
117    /// Documentation comment for the field.
118    pub doc_comment: Option<String>,
119    /// Visibility of the field.
120    pub visibility: Visibility,
121    /// Attributes on the field.
122    pub attributes: Vec<String>,
123}
124
125/// Represents a method implemented on a struct.
126#[derive(Debug, Clone, Serialize, Deserialize)]
127pub struct MethodInfo {
128    /// The name of the method.
129    pub name: String,
130    /// Documentation comment for the method.
131    pub doc_comment: Option<String>,
132    /// The file where this method is defined.
133    pub file_path: String,
134    /// Line number where the method starts.
135    pub line_number: usize,
136    /// Visibility of the method.
137    pub visibility: Visibility,
138    /// Whether this is an async method.
139    pub is_async: bool,
140    /// Whether this is a const method.
141    pub is_const: bool,
142    /// Whether this is an unsafe method.
143    pub is_unsafe: bool,
144    /// Generic parameters if any.
145    pub generics: Vec<String>,
146    /// Parameters of the method.
147    pub parameters: Vec<ParameterInfo>,
148    /// Return type of the method (None for `-> ()`).
149    pub return_type: Option<String>,
150    /// The receiver type (self, &self, &mut self, or None for associated functions).
151    pub receiver: Option<Receiver>,
152}
153
154/// Represents a method parameter.
155#[derive(Debug, Clone, Serialize, Deserialize)]
156pub struct ParameterInfo {
157    /// The name of the parameter.
158    pub name: String,
159    /// The type of the parameter as a string.
160    pub ty: String,
161}
162
163/// Represents the receiver of a method (self parameter).
164#[derive(Debug, Clone, Serialize, Deserialize)]
165pub enum Receiver {
166    /// `self` - takes ownership.
167    Value,
168    /// `&self` - immutable borrow.
169    Ref,
170    /// `&mut self` - mutable borrow.
171    RefMut,
172    /// `self: Box<Self>` or other explicit receiver types.
173    Explicit(String),
174}
175
176/// Represents the visibility of a Rust item.
177#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
178pub enum Visibility {
179    /// Private (no visibility modifier).
180    Private,
181    /// `pub` - public.
182    Public,
183    /// `pub(crate)` - visible within the crate.
184    Crate,
185    /// `pub(super)` - visible to the parent module.
186    Super,
187    /// `pub(in path)` - visible within a specific path.
188    Restricted(String),
189}
190
191impl Default for Visibility {
192    fn default() -> Self {
193        Visibility::Private
194    }
195}
196
197impl std::fmt::Display for Visibility {
198    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
199        match self {
200            Visibility::Private => write!(f, ""),
201            Visibility::Public => write!(f, "pub"),
202            Visibility::Crate => write!(f, "pub(crate)"),
203            Visibility::Super => write!(f, "pub(super)"),
204            Visibility::Restricted(path) => write!(f, "pub(in {})", path),
205        }
206    }
207}
208
209#[cfg(test)]
210mod tests {
211    use super::*;
212
213    #[test]
214    fn test_codebase_new() {
215        let codebase = CodeBase::new();
216        assert!(codebase.enums.is_empty());
217        assert!(codebase.structs.is_empty());
218        assert!(codebase.files.is_empty());
219    }
220
221    #[test]
222    fn test_codebase_merge() {
223        let mut codebase1 = CodeBase::new();
224        codebase1.enums.push(EnumInfo {
225            name: "TestEnum".to_string(),
226            doc_comment: None,
227            file_path: "test.rs".to_string(),
228            line_number: 1,
229            visibility: Visibility::Public,
230            generics: vec![],
231            derives: vec![],
232            attributes: vec![],
233            variants: vec![],
234        });
235
236        let mut codebase2 = CodeBase::new();
237        codebase2.structs.push(StructInfo {
238            name: "TestStruct".to_string(),
239            doc_comment: None,
240            file_path: "test.rs".to_string(),
241            line_number: 10,
242            visibility: Visibility::Public,
243            generics: vec![],
244            derives: vec![],
245            attributes: vec![],
246            fields: vec![],
247            methods: vec![],
248        });
249
250        codebase1.merge(codebase2);
251        assert_eq!(codebase1.enums.len(), 1);
252        assert_eq!(codebase1.structs.len(), 1);
253    }
254
255    #[test]
256    fn test_visibility_display() {
257        assert_eq!(Visibility::Private.to_string(), "");
258        assert_eq!(Visibility::Public.to_string(), "pub");
259        assert_eq!(Visibility::Crate.to_string(), "pub(crate)");
260        assert_eq!(Visibility::Super.to_string(), "pub(super)");
261        assert_eq!(
262            Visibility::Restricted("crate::module".to_string()).to_string(),
263            "pub(in crate::module)"
264        );
265    }
266}