Skip to main content

debugger/setup/
registry.rs

1//! Debugger registry and metadata
2//!
3//! Contains information about all supported debuggers and their installation methods.
4
5use super::installer::Installer;
6use std::fmt;
7use std::sync::Arc;
8
9/// Supported platforms
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum Platform {
12    Linux,
13    MacOS,
14    Windows,
15}
16
17impl Platform {
18    /// Get the current platform
19    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; // Default fallback
31    }
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/// Information about a debugger
45#[derive(Debug, Clone)]
46pub struct DebuggerInfo {
47    /// Unique identifier (e.g., "lldb", "codelldb")
48    pub id: &'static str,
49    /// Display name
50    pub name: &'static str,
51    /// Supported languages
52    pub languages: &'static [&'static str],
53    /// Supported platforms
54    pub platforms: &'static [Platform],
55    /// Brief description
56    pub description: &'static str,
57    /// Whether this is the primary adapter for its languages
58    pub primary: bool,
59}
60
61/// All available debuggers
62static 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
121/// Get all registered debuggers
122pub fn all_debuggers() -> &'static [DebuggerInfo] {
123    DEBUGGERS
124}
125
126/// Get debugger info by ID
127pub fn get_debugger(id: &str) -> Option<&'static DebuggerInfo> {
128    DEBUGGERS.iter().find(|d| d.id == id)
129}
130
131/// Get debuggers for a specific language
132pub fn debuggers_for_language(language: &str) -> Vec<&'static DebuggerInfo> {
133    DEBUGGERS
134        .iter()
135        .filter(|d| d.languages.contains(&language))
136        .collect()
137}
138
139/// Get the primary debugger for a language
140pub 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
146/// Get an installer for a debugger
147pub 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}