waterui_cli/toolchain/
doctor.rs1use crate::{
4 android::toolchain::{AndroidNdk, AndroidSdk, Java},
5 apple::toolchain::{AppleSdk, Xcode},
6 toolchain::Toolchain,
7};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum CheckStatus {
12 Ok,
14 Missing,
16 Skipped,
18}
19
20#[derive(Debug)]
22pub struct DoctorItem {
23 pub name: &'static str,
25 pub status: CheckStatus,
27 pub message: Option<String>,
29 pub fixable: bool,
31}
32
33impl DoctorItem {
34 const fn ok(name: &'static str) -> Self {
35 Self {
36 name,
37 status: CheckStatus::Ok,
38 message: None,
39 fixable: false,
40 }
41 }
42
43 fn missing(name: &'static str, message: impl Into<String>) -> Self {
44 Self {
45 name,
46 status: CheckStatus::Missing,
47 message: Some(message.into()),
48 fixable: false,
49 }
50 }
51
52 const fn skipped(name: &'static str) -> Self {
53 Self {
54 name,
55 status: CheckStatus::Skipped,
56 message: None,
57 fixable: false,
58 }
59 }
60}
61
62pub async fn doctor() -> Vec<DoctorItem> {
64 let mut items = Vec::new();
65
66 if cfg!(target_os = "macos") {
68 match Xcode.check().await {
69 Ok(()) => items.push(DoctorItem::ok("Xcode")),
70 Err(e) => items.push(DoctorItem::missing("Xcode", e.to_string())),
71 }
72
73 match AppleSdk::Ios.check().await {
75 Ok(()) => items.push(DoctorItem::ok("iOS SDK")),
76 Err(e) => items.push(DoctorItem::missing("iOS SDK", e.to_string())),
77 }
78
79 match AppleSdk::Macos.check().await {
81 Ok(()) => items.push(DoctorItem::ok("macOS SDK")),
82 Err(e) => items.push(DoctorItem::missing("macOS SDK", e.to_string())),
83 }
84 } else {
85 items.push(DoctorItem::skipped("Xcode"));
86 items.push(DoctorItem::skipped("iOS SDK"));
87 items.push(DoctorItem::skipped("macOS SDK"));
88 }
89
90 match AndroidSdk.check().await {
92 Ok(()) => items.push(DoctorItem::ok("Android SDK")),
93 Err(e) => items.push(DoctorItem::missing("Android SDK", e.to_string())),
94 }
95
96 match AndroidNdk.check().await {
98 Ok(()) => items.push(DoctorItem::ok("Android NDK")),
99 Err(e) => items.push(DoctorItem::missing("Android NDK", e.to_string())),
100 }
101
102 match Java::detect_path().await {
104 Some(_) => items.push(DoctorItem::ok("Java")),
105 None => items.push(DoctorItem::missing(
106 "Java",
107 "Install JDK or set JAVA_HOME. Android Studio includes a bundled JDK.",
108 )),
109 }
110
111 items
112}