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: "lldb",
65        name: "lldb-dap",
66        languages: &["c", "cpp", "rust", "swift"],
67        platforms: &[Platform::Linux, Platform::MacOS],
68        description: "LLVM's native DAP adapter",
69        primary: true,
70    },
71    DebuggerInfo {
72        id: "codelldb",
73        name: "CodeLLDB",
74        languages: &["c", "cpp", "rust"],
75        platforms: &[Platform::Linux, Platform::MacOS, Platform::Windows],
76        description: "Feature-rich LLDB-based debugger",
77        primary: false,
78    },
79    DebuggerInfo {
80        id: "python",
81        name: "debugpy",
82        languages: &["python"],
83        platforms: &[Platform::Linux, Platform::MacOS, Platform::Windows],
84        description: "Microsoft's Python debugger",
85        primary: true,
86    },
87    DebuggerInfo {
88        id: "go",
89        name: "Delve",
90        languages: &["go"],
91        platforms: &[Platform::Linux, Platform::MacOS, Platform::Windows],
92        description: "Go debugger with DAP support",
93        primary: true,
94    },
95];
96
97/// Get all registered debuggers
98pub fn all_debuggers() -> &'static [DebuggerInfo] {
99    DEBUGGERS
100}
101
102/// Get debugger info by ID
103pub fn get_debugger(id: &str) -> Option<&'static DebuggerInfo> {
104    DEBUGGERS.iter().find(|d| d.id == id)
105}
106
107/// Get debuggers for a specific language
108pub fn debuggers_for_language(language: &str) -> Vec<&'static DebuggerInfo> {
109    DEBUGGERS
110        .iter()
111        .filter(|d| d.languages.contains(&language))
112        .collect()
113}
114
115/// Get the primary debugger for a language
116pub fn primary_debugger_for_language(language: &str) -> Option<&'static DebuggerInfo> {
117    DEBUGGERS
118        .iter()
119        .find(|d| d.languages.contains(&language) && d.primary)
120}
121
122/// Get an installer for a debugger
123pub fn get_installer(id: &str) -> Option<Arc<dyn Installer>> {
124    use super::adapters;
125
126    match id {
127        "lldb" => Some(Arc::new(adapters::lldb::LldbInstaller)),
128        "codelldb" => Some(Arc::new(adapters::codelldb::CodeLldbInstaller)),
129        "python" => Some(Arc::new(adapters::debugpy::DebugpyInstaller)),
130        "go" => Some(Arc::new(adapters::delve::DelveInstaller)),
131        _ => None,
132    }
133}
134
135#[cfg(test)]
136mod tests {
137    use super::*;
138
139    #[test]
140    fn test_all_debuggers_has_entries() {
141        assert!(!all_debuggers().is_empty());
142    }
143
144    #[test]
145    fn test_get_debugger() {
146        assert!(get_debugger("lldb").is_some());
147        assert!(get_debugger("nonexistent").is_none());
148    }
149
150    #[test]
151    fn test_debuggers_for_language() {
152        let rust_debuggers = debuggers_for_language("rust");
153        assert!(!rust_debuggers.is_empty());
154    }
155}