Skip to main content

rust_analyzer_cli/daemon/
state.rs

1use crate::lsp::client::LspClient;
2use std::path::PathBuf;
3use std::sync::Arc;
4use tokio::sync::RwLock;
5
6pub struct AppState {
7    pub workspace_root: PathBuf,
8    pub lsp_client: Arc<RwLock<Option<Arc<LspClient>>>>,
9}
10
11impl AppState {
12    pub fn new(workspace_root: PathBuf) -> Self {
13        let canonical_root = workspace_root
14            .canonicalize()
15            .unwrap_or_else(|_| workspace_root.clone());
16        Self {
17            workspace_root: canonical_root,
18            lsp_client: Arc::new(RwLock::new(None)),
19        }
20    }
21
22
23    pub async fn get_or_start_lsp(&self) -> anyhow::Result<Arc<LspClient>> {
24        {
25            let lock = self.lsp_client.read().await;
26            if let Some(client) = lock.as_ref() {
27                return Ok(client.clone());
28            }
29        }
30
31        let mut lock = self.lsp_client.write().await;
32        if let Some(client) = lock.as_ref() {
33            return Ok(client.clone());
34        }
35
36        let client = Arc::new(LspClient::start(&self.workspace_root).await?);
37        *lock = Some(client.clone());
38        Ok(client)
39    }
40
41    pub async fn refresh_lsp(&self) -> anyhow::Result<()> {
42        let mut lock = self.lsp_client.write().await;
43        *lock = None;
44        let client = Arc::new(LspClient::start(&self.workspace_root).await?);
45        *lock = Some(client);
46        Ok(())
47    }
48}