use std::path::PathBuf;
use thiserror::Error;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Language {
Rust,
TypeScript,
JavaScript,
Python,
Go,
Cpp,
C,
}
impl std::fmt::Display for Language {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Language::Rust => write!(f, "rust"),
Language::TypeScript => write!(f, "typescript"),
Language::JavaScript => write!(f, "javascript"),
Language::Python => write!(f, "python"),
Language::Go => write!(f, "go"),
Language::Cpp => write!(f, "cpp"),
Language::C => write!(f, "c"),
}
}
}
impl Language {
pub fn language_id(&self) -> &'static str {
match self {
Language::Rust => "rust",
Language::TypeScript => "typescript",
Language::JavaScript => "javascript",
Language::Python => "python",
Language::Go => "go",
Language::Cpp => "cpp",
Language::C => "c",
}
}
pub fn from_extension(ext: &str) -> Option<Self> {
match ext.to_lowercase().as_str() {
"rs" => Some(Language::Rust),
"ts" | "tsx" => Some(Language::TypeScript),
"js" | "jsx" | "mjs" | "cjs" => Some(Language::JavaScript),
"py" | "pyi" => Some(Language::Python),
"go" => Some(Language::Go),
"cpp" | "cc" | "cxx" | "hpp" | "hxx" => Some(Language::Cpp),
"c" | "h" => Some(Language::C),
_ => None,
}
}
pub fn from_str(s: &str) -> Option<Self> {
match s.to_lowercase().as_str() {
"rust" | "rs" => Some(Language::Rust),
"typescript" | "ts" => Some(Language::TypeScript),
"javascript" | "js" => Some(Language::JavaScript),
"python" | "py" => Some(Language::Python),
"go" | "golang" => Some(Language::Go),
"cpp" | "c++" => Some(Language::Cpp),
"c" => Some(Language::C),
_ => None,
}
}
}
#[derive(Error, Debug)]
pub enum LspMcpError {
#[error("No active workspace. Call lsp_activate_workspace first.")]
NoActiveWorkspace,
#[error("Workspace not found: {0}")]
WorkspaceNotFound(PathBuf),
#[error("Language server not running for {language} in {workspace}")]
ServerNotRunning {
language: Language,
workspace: PathBuf,
},
#[error("Language server failed to start: {0}")]
ServerStartFailed(String),
#[error("Language server initialization failed: {0}")]
InitializationFailed(String),
#[error("LSP request timed out after {0} seconds")]
RequestTimeout(u64),
#[error("LSP protocol error: {0}")]
ProtocolError(String),
#[error("File not found: {0}")]
FileNotFound(PathBuf),
#[error("Unsupported language: {0}")]
UnsupportedLanguage(String),
#[error("Invalid position: line {line}, character {character}")]
InvalidPosition { line: u32, character: u32 },
#[error("Language server not available: {0}")]
ServerNotAvailable(String),
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("JSON error: {0}")]
Json(#[from] serde_json::Error),
#[error("Channel send error")]
ChannelSend,
#[error("Channel receive error")]
ChannelRecv,
}
pub type Result<T> = std::result::Result<T, LspMcpError>;