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    pub async fn get_or_start_lsp(&self) -> anyhow::Result<Arc<LspClient>> {
23        {
24            let lock = self.lsp_client.read().await;
25            if let Some(client) = lock.as_ref() {
26                return Ok(client.clone());
27            }
28        }
29
30        let mut lock = self.lsp_client.write().await;
31        if let Some(client) = lock.as_ref() {
32            return Ok(client.clone());
33        }
34
35        let client = Arc::new(LspClient::start(&self.workspace_root).await?);
36        *lock = Some(client.clone());
37        Ok(client)
38    }
39
40    pub async fn refresh_lsp(&self) -> anyhow::Result<()> {
41        let mut lock = self.lsp_client.write().await;
42        *lock = None;
43        let client = Arc::new(LspClient::start(&self.workspace_root).await?);
44        *lock = Some(client);
45        Ok(())
46    }
47}