ai_code_buddy/
lib.rs

1pub mod args;
2pub mod core;
3pub mod theme;
4pub mod version;
5
6// Re-export version constants for convenience
7pub use version::{APP_NAME, APP_VERSION};
8
9// Platform guards for GPU features to keep CI/platform builds sane
10// NVIDIA CUDA must only be built on Windows runners
11#[cfg(all(feature = "gpu-cuda", not(target_os = "windows")))]
12compile_error!(
13    "The `gpu-cuda` feature is only supported on Windows builds. Remove the feature or run on a Windows runner."
14);
15// Apple Metal must only be built on macOS
16#[cfg(all(feature = "gpu-metal", not(target_os = "macos")))]
17compile_error!(
18    "The `gpu-metal` feature is only supported on macOS builds. Remove the feature or run on a macOS runner."
19);
20
21pub mod widgets {
22    pub mod analysis;
23    pub mod credits;
24    pub mod overview;
25    pub mod reports;
26}
27
28pub mod widget_states {
29    pub mod analysis;
30    pub mod credits;
31    pub mod overview;
32    pub mod reports;
33}
34
35pub mod events {
36    pub mod analysis;
37    pub mod app;
38    pub mod credits;
39    pub mod overview;
40    pub mod reports;
41}
42
43pub mod bevy_states {
44    pub mod app;
45}
46
47// Re-export commonly used types for easier testing
48pub use args::{Args, OutputFormat};
49pub use core::analysis::perform_analysis;
50
51// Re-export main application functions for testing
52pub use main_functions::*;
53
54mod main_functions {
55    use crate::{args::Args, bevy_states::app::AppState, events::app::AppEvent};
56    use bevy::prelude::*;
57    use bevy_ratatui::event::{KeyEvent, MouseEvent};
58
59    pub fn initialize_app(mut next_state: ResMut<NextState<AppState>>, args: Res<Args>) {
60        println!("🚀 AI Code Buddy v{} - Initializing...", crate::APP_VERSION);
61        println!("📂 Repository: {}", args.repo_path);
62        println!(
63            "🌿 Branches: {} → {}",
64            args.source_branch, args.target_branch
65        );
66
67        next_state.set(AppState::Overview);
68    }
69
70    pub fn app_events_handler(
71        _app_state: Res<State<AppState>>,
72        mut send_app_state: ResMut<NextState<AppState>>,
73        mut app_events: EventReader<AppEvent>,
74        mut app_exit: EventWriter<AppExit>,
75    ) {
76        for event in app_events.read() {
77            match event {
78                AppEvent::SwitchTo(new_state) => {
79                    send_app_state.set(*new_state);
80                }
81                AppEvent::Exit => {
82                    app_exit.send_default();
83                }
84            }
85        }
86    }
87
88    pub fn keyboard_events_handler(
89        app_state: Res<State<AppState>>,
90        mut keyboard_events: EventReader<KeyEvent>,
91        mut overview_events: EventWriter<crate::events::overview::OverviewEvent>,
92        mut analysis_events: EventWriter<crate::events::analysis::AnalysisEvent>,
93        mut reports_events: EventWriter<crate::events::reports::ReportsEvent>,
94        mut credits_events: EventWriter<crate::events::credits::CreditsEvent>,
95        mut app_events: EventWriter<AppEvent>,
96    ) {
97        let app_state = app_state.get();
98
99        for event in keyboard_events.read() {
100            // Global key bindings
101            if let crossterm::event::KeyCode::Char('q') = event.code {
102                if event.kind == crossterm::event::KeyEventKind::Release {
103                    app_events.send(AppEvent::Exit);
104                    continue;
105                }
106            }
107
108            match app_state {
109                AppState::Overview => {
110                    overview_events.send(crate::events::overview::OverviewEvent::KeyEvent(
111                        event.clone(),
112                    ));
113                }
114                AppState::Analysis => {
115                    analysis_events.send(crate::events::analysis::AnalysisEvent::KeyEvent(
116                        event.clone(),
117                    ));
118                }
119                AppState::Reports => {
120                    reports_events.send(crate::events::reports::ReportsEvent::KeyEvent(
121                        event.clone(),
122                    ));
123                }
124                AppState::Credits => {
125                    credits_events.send(crate::events::credits::CreditsEvent::KeyEvent(
126                        event.clone(),
127                    ));
128                }
129            }
130        }
131    }
132
133    pub fn mouse_events_handler(
134        app_state: Res<State<AppState>>,
135        mut mouse_events: EventReader<MouseEvent>,
136        mut overview_events: EventWriter<crate::events::overview::OverviewEvent>,
137        mut analysis_events: EventWriter<crate::events::analysis::AnalysisEvent>,
138        mut reports_events: EventWriter<crate::events::reports::ReportsEvent>,
139        mut credits_events: EventWriter<crate::events::credits::CreditsEvent>,
140    ) {
141        let app_state = app_state.get();
142
143        for event in mouse_events.read() {
144            match app_state {
145                AppState::Overview => {
146                    overview_events
147                        .send(crate::events::overview::OverviewEvent::MouseEvent(*event));
148                }
149                AppState::Analysis => {
150                    analysis_events
151                        .send(crate::events::analysis::AnalysisEvent::MouseEvent(*event));
152                }
153                AppState::Reports => {
154                    reports_events.send(crate::events::reports::ReportsEvent::MouseEvent(*event));
155                }
156                AppState::Credits => {
157                    credits_events.send(crate::events::credits::CreditsEvent::MouseEvent(*event));
158                }
159            }
160        }
161    }
162}
163pub use core::review::Review;