ralph/commands/doctor/
types.rs1use serde::Serialize;
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
19#[serde(rename_all = "PascalCase")]
20pub enum CheckSeverity {
21 Success,
23 Warning,
25 Error,
27}
28
29#[derive(Debug, Clone, Serialize)]
31pub struct CheckResult {
32 pub category: String,
34 pub check: String,
36 pub severity: CheckSeverity,
38 pub message: String,
40 pub fix_available: bool,
42 #[serde(skip_serializing_if = "Option::is_none")]
44 pub fix_applied: Option<bool>,
45 #[serde(skip_serializing_if = "Option::is_none")]
47 pub suggested_fix: Option<String>,
48}
49
50impl CheckResult {
51 pub fn success(category: &str, check: &str, message: &str) -> Self {
53 Self {
54 category: category.to_string(),
55 check: check.to_string(),
56 severity: CheckSeverity::Success,
57 message: message.to_string(),
58 fix_available: false,
59 fix_applied: None,
60 suggested_fix: None,
61 }
62 }
63
64 pub fn warning(
66 category: &str,
67 check: &str,
68 message: &str,
69 fix_available: bool,
70 suggested_fix: Option<&str>,
71 ) -> Self {
72 Self {
73 category: category.to_string(),
74 check: check.to_string(),
75 severity: CheckSeverity::Warning,
76 message: message.to_string(),
77 fix_available,
78 fix_applied: None,
79 suggested_fix: suggested_fix.map(|s| s.to_string()),
80 }
81 }
82
83 pub fn error(
85 category: &str,
86 check: &str,
87 message: &str,
88 fix_available: bool,
89 suggested_fix: Option<&str>,
90 ) -> Self {
91 Self {
92 category: category.to_string(),
93 check: check.to_string(),
94 severity: CheckSeverity::Error,
95 message: message.to_string(),
96 fix_available,
97 fix_applied: None,
98 suggested_fix: suggested_fix.map(|s| s.to_string()),
99 }
100 }
101
102 pub fn with_fix_applied(mut self, applied: bool) -> Self {
104 self.fix_applied = Some(applied);
105 self
106 }
107}
108
109#[derive(Debug, Clone, Serialize)]
111pub struct Summary {
112 pub total: usize,
114 pub passed: usize,
116 pub warnings: usize,
118 pub errors: usize,
120 pub fixes_applied: usize,
122 pub fixes_failed: usize,
124}
125
126#[derive(Debug, Clone, Serialize)]
128pub struct DoctorReport {
129 pub success: bool,
131 pub checks: Vec<CheckResult>,
133 pub summary: Summary,
135}
136
137impl DoctorReport {
138 pub fn new() -> Self {
140 Self {
141 success: true,
142 checks: Vec::new(),
143 summary: Summary {
144 total: 0,
145 passed: 0,
146 warnings: 0,
147 errors: 0,
148 fixes_applied: 0,
149 fixes_failed: 0,
150 },
151 }
152 }
153
154 pub fn add(&mut self, result: CheckResult) {
156 self.summary.total += 1;
157 match result.severity {
158 CheckSeverity::Success => self.summary.passed += 1,
159 CheckSeverity::Warning => self.summary.warnings += 1,
160 CheckSeverity::Error => {
161 self.summary.errors += 1;
162 self.success = false;
163 }
164 }
165 if result.fix_applied == Some(true) {
166 self.summary.fixes_applied += 1;
167 } else if result.fix_applied == Some(false) {
168 self.summary.fixes_failed += 1;
169 }
170 self.checks.push(result);
171 }
172}
173
174impl Default for DoctorReport {
175 fn default() -> Self {
176 Self::new()
177 }
178}