1use super::installer::Installer;
6use std::fmt;
7use std::sync::Arc;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum Platform {
12 Linux,
13 MacOS,
14 Windows,
15}
16
17impl Platform {
18 pub fn current() -> Self {
20 #[cfg(target_os = "linux")]
21 return Platform::Linux;
22
23 #[cfg(target_os = "macos")]
24 return Platform::MacOS;
25
26 #[cfg(target_os = "windows")]
27 return Platform::Windows;
28
29 #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))]
30 return Platform::Linux; }
32}
33
34impl fmt::Display for Platform {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 match self {
37 Platform::Linux => write!(f, "linux"),
38 Platform::MacOS => write!(f, "macos"),
39 Platform::Windows => write!(f, "windows"),
40 }
41 }
42}
43
44#[derive(Debug, Clone)]
46pub struct DebuggerInfo {
47 pub id: &'static str,
49 pub name: &'static str,
51 pub languages: &'static [&'static str],
53 pub platforms: &'static [Platform],
55 pub description: &'static str,
57 pub primary: bool,
59}
60
61static DEBUGGERS: &[DebuggerInfo] = &[
63 DebuggerInfo {
64 id: "gdb",
65 name: "GDB",
66 languages: &["c", "cpp"],
67 platforms: &[Platform::Linux, Platform::MacOS, Platform::Windows],
68 description: "GDB native DAP adapter",
69 primary: true,
70 },
71 DebuggerInfo {
72 id: "cuda-gdb",
73 name: "CUDA-GDB",
74 languages: &["cuda", "c", "cpp"],
75 platforms: &[Platform::Linux],
76 description: "NVIDIA CUDA debugger with DAP support",
77 primary: true,
78 },
79 DebuggerInfo {
80 id: "lldb",
81 name: "lldb-dap",
82 languages: &["c", "cpp", "rust", "swift"],
83 platforms: &[Platform::Linux, Platform::MacOS],
84 description: "LLVM's native DAP adapter",
85 primary: true,
86 },
87 DebuggerInfo {
88 id: "codelldb",
89 name: "CodeLLDB",
90 languages: &["c", "cpp", "rust"],
91 platforms: &[Platform::Linux, Platform::MacOS, Platform::Windows],
92 description: "Feature-rich LLDB-based debugger",
93 primary: false,
94 },
95 DebuggerInfo {
96 id: "python",
97 name: "debugpy",
98 languages: &["python"],
99 platforms: &[Platform::Linux, Platform::MacOS, Platform::Windows],
100 description: "Microsoft's Python debugger",
101 primary: true,
102 },
103 DebuggerInfo {
104 id: "go",
105 name: "Delve",
106 languages: &["go"],
107 platforms: &[Platform::Linux, Platform::MacOS, Platform::Windows],
108 description: "Go debugger with DAP support",
109 primary: true,
110 },
111 DebuggerInfo {
112 id: "js-debug",
113 name: "js-debug",
114 languages: &["javascript", "typescript"],
115 platforms: &[Platform::Linux, Platform::MacOS, Platform::Windows],
116 description: "Microsoft's JavaScript/TypeScript debugger",
117 primary: true,
118 },
119];
120
121pub fn all_debuggers() -> &'static [DebuggerInfo] {
123 DEBUGGERS
124}
125
126pub fn get_debugger(id: &str) -> Option<&'static DebuggerInfo> {
128 DEBUGGERS.iter().find(|d| d.id == id)
129}
130
131pub fn debuggers_for_language(language: &str) -> Vec<&'static DebuggerInfo> {
133 DEBUGGERS
134 .iter()
135 .filter(|d| d.languages.contains(&language))
136 .collect()
137}
138
139pub fn primary_debugger_for_language(language: &str) -> Option<&'static DebuggerInfo> {
141 DEBUGGERS
142 .iter()
143 .find(|d| d.languages.contains(&language) && d.primary)
144}
145
146pub fn get_installer(id: &str) -> Option<Arc<dyn Installer>> {
148 use super::adapters;
149
150 match id {
151 "gdb" => Some(Arc::new(adapters::gdb::GdbInstaller)),
152 "cuda-gdb" => Some(Arc::new(adapters::cuda_gdb::CudaGdbInstaller)),
153 "lldb" => Some(Arc::new(adapters::lldb::LldbInstaller)),
154 "codelldb" => Some(Arc::new(adapters::codelldb::CodeLldbInstaller)),
155 "python" => Some(Arc::new(adapters::debugpy::DebugpyInstaller)),
156 "go" => Some(Arc::new(adapters::delve::DelveInstaller)),
157 "js-debug" => Some(Arc::new(adapters::js_debug::JsDebugInstaller)),
158 _ => None,
159 }
160}
161
162#[cfg(test)]
163mod tests {
164 use super::*;
165
166 #[test]
167 fn test_all_debuggers_has_entries() {
168 assert!(!all_debuggers().is_empty());
169 }
170
171 #[test]
172 fn test_get_debugger() {
173 assert!(get_debugger("lldb").is_some());
174 assert!(get_debugger("nonexistent").is_none());
175 }
176
177 #[test]
178 fn test_debuggers_for_language() {
179 let rust_debuggers = debuggers_for_language("rust");
180 assert!(!rust_debuggers.is_empty());
181 }
182}