1pub mod analyzer;
8pub mod background;
9pub mod diff;
10pub mod notifier;
11pub mod platform;
12pub mod prompts;
13pub mod report;
14pub mod reviewer;
15
16pub mod fixer;
17
18use serde::{Deserialize, Serialize};
19use std::collections::HashMap;
20use std::fmt;
21use std::path::PathBuf;
22use std::str::FromStr;
23
24#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
26#[serde(rename_all = "lowercase")]
27pub enum AutoFixMode {
28 Pr,
30 Commit,
32 #[default]
34 Apply,
35}
36
37impl FromStr for AutoFixMode {
38 type Err = String;
39
40 fn from_str(s: &str) -> Result<Self, Self::Err> {
41 match s.to_lowercase().as_str() {
42 "pr" => Ok(AutoFixMode::Pr),
43 "commit" => Ok(AutoFixMode::Commit),
44 "apply" => Ok(AutoFixMode::Apply),
45 _ => Err(format!(
46 "invalid auto-fix mode '{}': expected pr, commit, or apply",
47 s
48 )),
49 }
50 }
51}
52
53impl fmt::Display for AutoFixMode {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 match self {
56 AutoFixMode::Pr => write!(f, "pr"),
57 AutoFixMode::Commit => write!(f, "commit"),
58 AutoFixMode::Apply => write!(f, "apply"),
59 }
60 }
61}
62
63#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
65pub enum Assessment {
66 Ready,
68 NeedsWork,
70 CriticalIssues,
72}
73
74impl fmt::Display for Assessment {
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76 match self {
77 Assessment::Ready => write!(f, "Ready"),
78 Assessment::NeedsWork => write!(f, "Needs Work"),
79 Assessment::CriticalIssues => write!(f, "Critical Issues"),
80 }
81 }
82}
83
84#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
86pub enum Severity {
87 Critical,
89 Important,
91 Minor,
93}
94
95impl fmt::Display for Severity {
96 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
97 match self {
98 Severity::Critical => write!(f, "Critical"),
99 Severity::Important => write!(f, "Important"),
100 Severity::Minor => write!(f, "Minor"),
101 }
102 }
103}
104
105#[derive(Debug, Clone, Serialize, Deserialize)]
107pub struct ReviewIssue {
108 pub severity: Severity,
110 pub category: String,
112 pub file: PathBuf,
114 pub line: Option<u32>,
116 pub message: String,
118 pub suggestion: Option<String>,
120}
121
122impl fmt::Display for ReviewIssue {
123 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124 write!(
125 f,
126 "[{}] {} ({}): {}",
127 self.severity,
128 self.file.display(),
129 self.category,
130 self.message
131 )
132 }
133}
134
135#[derive(Debug, Clone, Serialize, Deserialize)]
137pub struct ReviewSummary {
138 pub files_reviewed: usize,
140 pub total_issues: usize,
142 pub critical_count: usize,
144 pub important_count: usize,
146 pub minor_count: usize,
148 pub assessment: Assessment,
150 pub summary_text: String,
152}
153
154impl fmt::Display for ReviewSummary {
155 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
156 write!(
157 f,
158 "Review: {} ({} files, {} issues: {} critical, {} important, {} minor)",
159 self.assessment,
160 self.files_reviewed,
161 self.total_issues,
162 self.critical_count,
163 self.important_count,
164 self.minor_count
165 )
166 }
167}
168
169#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
171pub enum FileStatus {
172 Added,
174 Modified,
176 Deleted,
178 Renamed { from: PathBuf },
180}
181
182impl fmt::Display for FileStatus {
183 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
184 match self {
185 FileStatus::Added => write!(f, "Added"),
186 FileStatus::Modified => write!(f, "Modified"),
187 FileStatus::Deleted => write!(f, "Deleted"),
188 FileStatus::Renamed { from } => {
189 write!(f, "Renamed from {}", from.display())
190 }
191 }
192 }
193}
194
195#[derive(Debug, Clone, Serialize, Deserialize)]
197pub struct ReviewedFile {
198 pub path: PathBuf,
200 pub status: FileStatus,
202 pub issues: Vec<ReviewIssue>,
204}
205
206impl fmt::Display for ReviewedFile {
207 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
208 write!(
209 f,
210 "{} ({}, {} issues)",
211 self.path.display(),
212 self.status,
213 self.issues.len()
214 )
215 }
216}
217
218#[derive(Debug, Clone, Serialize, Deserialize)]
220pub struct AutoFix {
221 pub file: PathBuf,
223 pub line: Option<u32>,
225 pub description: String,
227}
228
229#[derive(Debug, Clone, Serialize, Deserialize)]
231pub struct ReviewResult {
232 pub summary: ReviewSummary,
234 pub files: Vec<ReviewedFile>,
236 pub issues: Vec<ReviewIssue>,
238 pub base_ref: String,
240 pub head_ref: String,
242 #[serde(default)]
244 pub auto_fixes: Vec<AutoFix>,
245}
246
247impl ReviewResult {
248 pub fn count_by_severity(&self) -> HashMap<Severity, usize> {
250 let mut counts = HashMap::new();
251 for issue in &self.issues {
252 *counts.entry(issue.severity).or_insert(0) += 1;
253 }
254 counts
255 }
256}
257
258impl fmt::Display for ReviewResult {
259 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
260 write!(
261 f,
262 "Review {}..{}: {}",
263 self.base_ref, self.head_ref, self.summary
264 )
265 }
266}