glua_ls 1.0.27

Language server for Garry's Mod Lua (GLua).
Documentation
use std::sync::Arc;

use lsp_types::{
    NumberOrString, ProgressParams, ProgressParamsValue, WorkDoneProgress, WorkDoneProgressBegin,
    WorkDoneProgressCreateParams, WorkDoneProgressEnd, WorkDoneProgressReport,
};

use crate::util::time_cancel_token;

use super::ClientProxy;

pub struct StatusBar {
    client: Arc<ClientProxy>,
}

#[derive(Debug, Clone, Copy)]
pub enum ProgressTask {
    LoadWorkspace = 0,
    DiagnoseWorkspace = 1,
    #[allow(dead_code)]
    RefreshIndex = 2,
}

impl ProgressTask {
    pub fn as_i32(&self) -> i32 {
        *self as i32
    }

    pub fn get_task_name(&self) -> &'static str {
        match self {
            ProgressTask::LoadWorkspace => "Loading workspace",
            ProgressTask::DiagnoseWorkspace => "Running diagnostics",
            ProgressTask::RefreshIndex => "Refreshing index",
        }
    }
}

impl StatusBar {
    pub fn new(client: Arc<ClientProxy>) -> Self {
        Self { client }
    }

    pub async fn create_progress_task(&self, task: ProgressTask) {
        let request_id = self.client.next_id();
        let cancel_token = time_cancel_token(std::time::Duration::from_secs(5));
        let _ = self
            .client
            .send_request(
                request_id,
                "window/workDoneProgress/create",
                WorkDoneProgressCreateParams {
                    token: NumberOrString::Number(task.as_i32()),
                },
                cancel_token,
            )
            .await;
        self.client.send_notification(
            "$/progress",
            ProgressParams {
                token: NumberOrString::Number(task as i32),
                value: ProgressParamsValue::WorkDone(WorkDoneProgress::Begin(
                    WorkDoneProgressBegin {
                        title: task.get_task_name().to_string(),
                        cancellable: Some(false),
                        message: Some(task.get_task_name().to_string()),
                        percentage: None,
                    },
                )),
            },
        )
    }

    pub fn update_progress_task(
        &self,
        task: ProgressTask,
        percentage: Option<u32>,
        message: Option<String>,
    ) {
        self.client.send_notification(
            "$/progress",
            ProgressParams {
                token: NumberOrString::Number(task.as_i32()),
                value: ProgressParamsValue::WorkDone(WorkDoneProgress::Report(
                    WorkDoneProgressReport {
                        percentage,
                        cancellable: Some(false),
                        message,
                    },
                )),
            },
        )
    }

    pub fn finish_progress_task(&self, task: ProgressTask, message: Option<String>) {
        self.client.send_notification(
            "$/progress",
            ProgressParams {
                token: NumberOrString::Number(task.as_i32()),
                value: ProgressParamsValue::WorkDone(WorkDoneProgress::End(WorkDoneProgressEnd {
                    message,
                })),
            },
        )
    }
}

#[cfg(test)]
mod tests {
    use super::ProgressTask;

    #[test]
    fn progress_task_names_are_concise() {
        assert_eq!(
            ProgressTask::LoadWorkspace.get_task_name(),
            "Loading workspace"
        );
        assert_eq!(
            ProgressTask::DiagnoseWorkspace.get_task_name(),
            "Running diagnostics"
        );
        assert_eq!(
            ProgressTask::RefreshIndex.get_task_name(),
            "Refreshing index"
        );
    }
}