use crate::error::{Language, LspMcpError, Result};
use crate::lsp::LanguageServerManager;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Debug, Serialize, Deserialize)]
pub struct ActivateWorkspaceResult {
pub workspace: String,
pub languages_started: Vec<String>,
pub languages_failed: Vec<String>,
}
pub fn activate_workspace(
manager: &LanguageServerManager,
workspace_path: &str,
languages: Option<Vec<String>>,
) -> Result<ActivateWorkspaceResult> {
let path = PathBuf::from(workspace_path);
if !path.exists() {
return Err(LspMcpError::WorkspaceNotFound(path));
}
let language_enums: Option<Vec<Language>> = languages.map(|langs| {
langs
.iter()
.filter_map(|l| Language::from_str(l))
.collect()
});
let requested_languages: Vec<String> = language_enums
.as_ref()
.map(|langs| langs.iter().map(|l| l.to_string()).collect())
.unwrap_or_default();
let started = manager.activate_workspace(path.clone(), language_enums)?;
let started_strings: Vec<String> = started.iter().map(|l| l.to_string()).collect();
let failed: Vec<String> = if requested_languages.is_empty() {
vec![]
} else {
requested_languages
.into_iter()
.filter(|l| !started_strings.contains(l))
.collect()
};
Ok(ActivateWorkspaceResult {
workspace: path.to_string_lossy().to_string(),
languages_started: started_strings,
languages_failed: failed,
})
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ListWorkspacesResult {
pub workspaces: Vec<WorkspaceEntry>,
pub active_workspace: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct WorkspaceEntry {
pub path: String,
pub languages: Vec<String>,
}
pub fn list_workspaces(manager: &LanguageServerManager) -> ListWorkspacesResult {
let workspaces = manager.list_workspaces();
let active = manager.active_workspace();
ListWorkspacesResult {
workspaces: workspaces
.into_iter()
.map(|w| WorkspaceEntry {
path: w.path.to_string_lossy().to_string(),
languages: w.languages.iter().map(|l| l.to_string()).collect(),
})
.collect(),
active_workspace: active.map(|p| p.to_string_lossy().to_string()),
}
}
pub fn deactivate_workspace(
manager: &LanguageServerManager,
workspace_path: &str,
) -> Result<String> {
let path = PathBuf::from(workspace_path);
manager.deactivate_workspace(&path)?;
Ok(format!("Deactivated workspace: {}", workspace_path))
}