1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5use std::path::PathBuf;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct ProjectContext {
14 pub project_type: ProjectType,
16 pub languages: Vec<Language>,
18 pub frameworks: Vec<Framework>,
20 pub structure: ProjectStructure,
22 pub patterns: Vec<DetectedPattern>,
24 pub dependencies: Vec<Dependency>,
26 pub architectural_intent: ArchitecturalIntent,
28 pub standards: StandardsProfile,
30}
31
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
34pub enum ProjectType {
35 Library,
37 Application,
39 Service,
41 Monorepo,
43 Unknown,
45}
46
47#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
49pub enum Language {
50 Rust,
52 TypeScript,
54 Python,
56 Go,
58 Java,
60 Kotlin,
62 CSharp,
64 Php,
66 Ruby,
68 Swift,
70 Dart,
72 Other(String),
74}
75
76#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
78pub struct Framework {
79 pub name: String,
81 pub version: Option<String>,
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize)]
87pub struct ProjectStructure {
88 pub root: PathBuf,
90 pub source_dirs: Vec<PathBuf>,
92 pub test_dirs: Vec<PathBuf>,
94 pub config_files: Vec<PathBuf>,
96 pub entry_points: Vec<PathBuf>,
98}
99
100#[derive(Debug, Clone, Serialize, Deserialize)]
102pub struct DetectedPattern {
103 pub name: String,
105 pub category: PatternCategory,
107 pub confidence: f32,
109 pub locations: Vec<PathBuf>,
111 pub description: String,
113}
114
115#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
117pub enum PatternCategory {
118 Architectural,
120 Design,
122 Coding,
124 Testing,
126 Configuration,
128}
129
130#[derive(Debug, Clone, Serialize, Deserialize)]
132pub struct Dependency {
133 pub name: String,
135 pub version: String,
137 pub constraints: Option<String>,
139 pub is_dev: bool,
141}
142
143#[derive(Debug, Clone, Serialize, Deserialize)]
149pub struct ArchitecturalIntent {
150 pub style: ArchitecturalStyle,
152 pub principles: Vec<String>,
154 pub constraints: Vec<String>,
156 pub decisions: Vec<ArchitecturalDecision>,
158}
159
160#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
162pub enum ArchitecturalStyle {
163 Layered,
165 Microservices,
167 EventDriven,
169 Monolithic,
171 Serverless,
173 Unknown,
175}
176
177#[derive(Debug, Clone, Serialize, Deserialize)]
179pub struct ArchitecturalDecision {
180 pub id: String,
182 pub title: String,
184 pub context: String,
186 pub decision: String,
188 pub consequences: Vec<String>,
190 pub date: DateTime<Utc>,
192}
193
194#[derive(Debug, Clone, Serialize, Deserialize)]
200pub struct CodeContext {
201 pub files: Vec<FileContext>,
203 pub symbols: Vec<Symbol>,
205 pub references: Vec<SymbolReference>,
207 pub total_tokens: usize,
209}
210
211#[derive(Debug, Clone, Serialize, Deserialize)]
213pub struct FileContext {
214 pub path: PathBuf,
216 pub relevance: f32,
218 pub summary: Option<String>,
220 pub content: Option<String>,
222}
223
224#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
226pub struct Symbol {
227 pub id: String,
229 pub name: String,
231 pub kind: SymbolKind,
233 pub file: PathBuf,
235 pub line: usize,
237 pub column: usize,
239 pub references: Vec<SymbolReference>,
241}
242
243#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
245pub enum SymbolKind {
246 Function,
248 Class,
250 Type,
252 Constant,
254 Variable,
256 Module,
258 Trait,
260 Enum,
262}
263
264#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
266pub struct SymbolReference {
267 pub symbol_id: String,
269 pub file: PathBuf,
271 pub line: usize,
273 pub kind: ReferenceKind,
275}
276
277#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
279pub enum ReferenceKind {
280 Definition,
282 Usage,
284 Import,
286 Export,
288}
289
290#[derive(Debug, Clone, Serialize, Deserialize)]
292pub struct SearchResult {
293 pub symbol: Symbol,
295 pub relevance: f32,
297 pub context: Option<String>,
299}
300
301#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
307pub struct StandardsProfile {
308 pub naming_conventions: NamingConventions,
310 pub formatting_style: FormattingStyle,
312 pub import_organization: ImportOrganization,
314 pub documentation_style: DocumentationStyle,
316}
317
318impl Default for NamingConventions {
319 fn default() -> Self {
320 NamingConventions {
321 function_case: CaseStyle::SnakeCase,
322 variable_case: CaseStyle::SnakeCase,
323 class_case: CaseStyle::PascalCase,
324 constant_case: CaseStyle::UpperCase,
325 }
326 }
327}
328
329impl Default for FormattingStyle {
330 fn default() -> Self {
331 FormattingStyle {
332 indent_size: 4,
333 indent_type: IndentType::Spaces,
334 line_length: 100,
335 }
336 }
337}
338
339impl Default for ImportOrganization {
340 fn default() -> Self {
341 ImportOrganization {
342 order: vec![
343 ImportGroup::Standard,
344 ImportGroup::External,
345 ImportGroup::Internal,
346 ],
347 sort_within_group: true,
348 }
349 }
350}
351
352impl Default for DocumentationStyle {
353 fn default() -> Self {
354 DocumentationStyle {
355 format: DocFormat::RustDoc,
356 required_for_public: true,
357 }
358 }
359}
360
361#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
363pub struct NamingConventions {
364 pub function_case: CaseStyle,
366 pub variable_case: CaseStyle,
368 pub class_case: CaseStyle,
370 pub constant_case: CaseStyle,
372}
373
374#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
376pub enum CaseStyle {
377 CamelCase,
379 SnakeCase,
381 PascalCase,
383 KebabCase,
385 UpperCase,
387 Mixed,
389}
390
391#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
393pub struct FormattingStyle {
394 pub indent_size: usize,
396 pub indent_type: IndentType,
398 pub line_length: usize,
400}
401
402#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
404pub enum IndentType {
405 Spaces,
407 Tabs,
409}
410
411#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
413pub struct ImportOrganization {
414 pub order: Vec<ImportGroup>,
416 pub sort_within_group: bool,
418}
419
420#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
422pub enum ImportGroup {
423 Standard,
425 External,
427 Internal,
429 Relative,
431}
432
433#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
435pub struct DocumentationStyle {
436 pub format: DocFormat,
438 pub required_for_public: bool,
440}
441
442#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
444pub enum DocFormat {
445 JavaDoc,
447 RustDoc,
449 JSDoc,
451 PythonDoc,
453}
454
455#[cfg(test)]
456mod tests {
457 use super::*;
458
459 #[test]
460 fn test_project_type_serialization() {
461 let project_type = ProjectType::Library;
462 let json = serde_json::to_string(&project_type).unwrap();
463 let deserialized: ProjectType = serde_json::from_str(&json).unwrap();
464 assert_eq!(project_type, deserialized);
465 }
466
467 #[test]
468 fn test_language_serialization() {
469 let language = Language::Rust;
470 let json = serde_json::to_string(&language).unwrap();
471 let deserialized: Language = serde_json::from_str(&json).unwrap();
472 assert_eq!(language, deserialized);
473 }
474
475 #[test]
476 fn test_symbol_kind_serialization() {
477 let kind = SymbolKind::Function;
478 let json = serde_json::to_string(&kind).unwrap();
479 let deserialized: SymbolKind = serde_json::from_str(&json).unwrap();
480 assert_eq!(kind, deserialized);
481 }
482
483 #[test]
484 fn test_case_style_serialization() {
485 let style = CaseStyle::SnakeCase;
486 let json = serde_json::to_string(&style).unwrap();
487 let deserialized: CaseStyle = serde_json::from_str(&json).unwrap();
488 assert_eq!(style, deserialized);
489 }
490
491 #[test]
492 fn test_project_context_creation() {
493 let context = ProjectContext {
494 project_type: ProjectType::Library,
495 languages: vec![Language::Rust],
496 frameworks: vec![],
497 structure: ProjectStructure {
498 root: PathBuf::from("/project"),
499 source_dirs: vec![PathBuf::from("/project/src")],
500 test_dirs: vec![PathBuf::from("/project/tests")],
501 config_files: vec![PathBuf::from("/project/Cargo.toml")],
502 entry_points: vec![],
503 },
504 patterns: vec![],
505 dependencies: vec![],
506 architectural_intent: ArchitecturalIntent {
507 style: ArchitecturalStyle::Layered,
508 principles: vec![],
509 constraints: vec![],
510 decisions: vec![],
511 },
512 standards: StandardsProfile {
513 naming_conventions: NamingConventions {
514 function_case: CaseStyle::SnakeCase,
515 variable_case: CaseStyle::SnakeCase,
516 class_case: CaseStyle::PascalCase,
517 constant_case: CaseStyle::UpperCase,
518 },
519 formatting_style: FormattingStyle {
520 indent_size: 4,
521 indent_type: IndentType::Spaces,
522 line_length: 100,
523 },
524 import_organization: ImportOrganization {
525 order: vec![
526 ImportGroup::Standard,
527 ImportGroup::External,
528 ImportGroup::Internal,
529 ],
530 sort_within_group: true,
531 },
532 documentation_style: DocumentationStyle {
533 format: DocFormat::RustDoc,
534 required_for_public: true,
535 },
536 },
537 };
538
539 assert_eq!(context.project_type, ProjectType::Library);
540 assert_eq!(context.languages.len(), 1);
541 }
542}