rust-analyzer-cli 0.4.0

A library and CLI tool built on top of rust-analyzer for codebase navigation
Documentation
use crate::lsp::client::LspClient;
use std::path::PathBuf;
use std::sync::Arc;
use tokio::sync::RwLock;

pub struct AppState {
    pub workspace_root: PathBuf,
    pub lsp_client: Arc<RwLock<Option<Arc<LspClient>>>>,
}

impl AppState {
    pub fn new(workspace_root: PathBuf) -> Self {
        let canonical_root = workspace_root
            .canonicalize()
            .unwrap_or_else(|_| workspace_root.clone());
        Self {
            workspace_root: canonical_root,
            lsp_client: Arc::new(RwLock::new(None)),
        }
    }


    pub async fn get_or_start_lsp(&self) -> anyhow::Result<Arc<LspClient>> {
        {
            let lock = self.lsp_client.read().await;
            if let Some(client) = lock.as_ref() {
                return Ok(client.clone());
            }
        }

        let mut lock = self.lsp_client.write().await;
        if let Some(client) = lock.as_ref() {
            return Ok(client.clone());
        }

        let client = Arc::new(LspClient::start(&self.workspace_root).await?);
        *lock = Some(client.clone());
        Ok(client)
    }

    pub async fn refresh_lsp(&self) -> anyhow::Result<()> {
        let mut lock = self.lsp_client.write().await;
        *lock = None;
        let client = Arc::new(LspClient::start(&self.workspace_root).await?);
        *lock = Some(client);
        Ok(())
    }
}