Skip to main content

lsp_mcp/
error.rs

1use std::path::PathBuf;
2use thiserror::Error;
3
4/// Language identifier for LSP servers
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6pub enum Language {
7    Rust,
8    TypeScript,
9    JavaScript,
10    Python,
11    Go,
12    Cpp,
13    C,
14}
15
16impl std::fmt::Display for Language {
17    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18        match self {
19            Language::Rust => write!(f, "rust"),
20            Language::TypeScript => write!(f, "typescript"),
21            Language::JavaScript => write!(f, "javascript"),
22            Language::Python => write!(f, "python"),
23            Language::Go => write!(f, "go"),
24            Language::Cpp => write!(f, "cpp"),
25            Language::C => write!(f, "c"),
26        }
27    }
28}
29
30impl Language {
31    /// Get the LSP language identifier string
32    pub fn language_id(&self) -> &'static str {
33        match self {
34            Language::Rust => "rust",
35            Language::TypeScript => "typescript",
36            Language::JavaScript => "javascript",
37            Language::Python => "python",
38            Language::Go => "go",
39            Language::Cpp => "cpp",
40            Language::C => "c",
41        }
42    }
43
44    /// Detect language from file extension
45    pub fn from_extension(ext: &str) -> Option<Self> {
46        match ext.to_lowercase().as_str() {
47            "rs" => Some(Language::Rust),
48            "ts" | "tsx" => Some(Language::TypeScript),
49            "js" | "jsx" | "mjs" | "cjs" => Some(Language::JavaScript),
50            "py" | "pyi" => Some(Language::Python),
51            "go" => Some(Language::Go),
52            "cpp" | "cc" | "cxx" | "hpp" | "hxx" => Some(Language::Cpp),
53            "c" | "h" => Some(Language::C),
54            _ => None,
55        }
56    }
57
58    /// Try to parse from string
59    pub fn from_str(s: &str) -> Option<Self> {
60        match s.to_lowercase().as_str() {
61            "rust" | "rs" => Some(Language::Rust),
62            "typescript" | "ts" => Some(Language::TypeScript),
63            "javascript" | "js" => Some(Language::JavaScript),
64            "python" | "py" => Some(Language::Python),
65            "go" | "golang" => Some(Language::Go),
66            "cpp" | "c++" => Some(Language::Cpp),
67            "c" => Some(Language::C),
68            _ => None,
69        }
70    }
71}
72
73/// Errors that can occur in the LSP MCP server
74#[derive(Error, Debug)]
75pub enum LspMcpError {
76    #[error("No active workspace. Call lsp_activate_workspace first.")]
77    NoActiveWorkspace,
78
79    #[error("Workspace not found: {0}")]
80    WorkspaceNotFound(PathBuf),
81
82    #[error("Language server not running for {language} in {workspace}")]
83    ServerNotRunning {
84        language: Language,
85        workspace: PathBuf,
86    },
87
88    #[error("Language server failed to start: {0}")]
89    ServerStartFailed(String),
90
91    #[error("Language server initialization failed: {0}")]
92    InitializationFailed(String),
93
94    #[error("LSP request timed out after {0} seconds")]
95    RequestTimeout(u64),
96
97    #[error("LSP protocol error: {0}")]
98    ProtocolError(String),
99
100    #[error("File not found: {0}")]
101    FileNotFound(PathBuf),
102
103    #[error("Unsupported language: {0}")]
104    UnsupportedLanguage(String),
105
106    #[error("Invalid position: line {line}, character {character}")]
107    InvalidPosition { line: u32, character: u32 },
108
109    #[error("Language server not available: {0}")]
110    ServerNotAvailable(String),
111
112    #[error("IO error: {0}")]
113    Io(#[from] std::io::Error),
114
115    #[error("JSON error: {0}")]
116    Json(#[from] serde_json::Error),
117
118    #[error("Channel send error")]
119    ChannelSend,
120
121    #[error("Channel receive error")]
122    ChannelRecv,
123}
124
125pub type Result<T> = std::result::Result<T, LspMcpError>;