beancount_language_server/
progress.rs

1use super::LspServerState;
2
3#[derive(Debug, Eq, PartialEq)]
4pub(crate) enum Progress {
5    Begin,
6    Report,
7    End,
8}
9
10impl Progress {
11    /// Builds a fractional progress value
12    pub(crate) fn fraction(done: usize, total: usize) -> f64 {
13        assert!(done <= total);
14        done as f64 / total.max(1) as f64
15    }
16}
17
18impl LspServerState {
19    // Reports progress to the user via the `WorkDoneProgress` protocol.
20    pub(crate) fn report_progress(
21        &mut self,
22        title: &str,
23        state: Progress,
24        message: Option<String>,
25        fraction: Option<f64>,
26    ) {
27        // TODO: Ensure that the client supports WorkDoneProgress
28
29        let percentage = fraction.map(|f| {
30            (0.0..=1.0).contains(&f);
31            (f * 100.0) as u32
32        });
33        let token = lsp_types::ProgressToken::String(format!("beancount/{}", title));
34        let work_done_progress = match state {
35            Progress::Begin => {
36                self.send_request::<lsp_types::request::WorkDoneProgressCreate>(
37                    lsp_types::WorkDoneProgressCreateParams {
38                        token: token.clone(),
39                    },
40                    |_, _| (),
41                );
42
43                lsp_types::WorkDoneProgress::Begin(lsp_types::WorkDoneProgressBegin {
44                    title: title.into(),
45                    cancellable: None,
46                    message,
47                    percentage,
48                })
49            }
50            Progress::Report => {
51                lsp_types::WorkDoneProgress::Report(lsp_types::WorkDoneProgressReport {
52                    cancellable: None,
53                    message,
54                    percentage,
55                })
56            }
57            Progress::End => {
58                lsp_types::WorkDoneProgress::End(lsp_types::WorkDoneProgressEnd { message })
59            }
60        };
61        self.send_notification::<lsp_types::notification::Progress>(lsp_types::ProgressParams {
62            token,
63            value: lsp_types::ProgressParamsValue::WorkDone(work_done_progress),
64        });
65    }
66}
67/*pub async fn progress_begin(client: &Client, title: &str) -> ProgressToken {
68    let token = NumberOrString::String(format!("beancount-language-server/{}", title));
69    let begin = WorkDoneProgressBegin {
70        title: title.to_string(),
71        cancellable: Some(false),
72        message: None,
73        percentage: Some(100),
74    };
75
76    client
77        .send_request::<WorkDoneProgressCreate>(WorkDoneProgressCreateParams {
78            token: token.clone(),
79        })
80        .await
81        .unwrap();
82
83    client
84        .send_notification::<Progress>(ProgressParams {
85            token: token.clone(),
86            value: ProgressParamsValue::WorkDone(WorkDoneProgress::Begin(begin)),
87        })
88        .await;
89    token
90}
91
92pub async fn progress(client: &Client, token: ProgressToken, message: String) {
93    let step = WorkDoneProgressReport {
94        cancellable: Some(false),
95        message: Some(message),
96        percentage: None, //Some(pcnt),
97    };
98    client
99        .send_notification::<Progress>(ProgressParams {
100            token,
101            value: ProgressParamsValue::WorkDone(WorkDoneProgress::Report(step)),
102        })
103        .await;
104}
105
106pub async fn progress_end(client: &Client, token: ProgressToken) {
107    client
108        .send_notification::<Progress>(ProgressParams {
109            token,
110            value: ProgressParamsValue::WorkDone(WorkDoneProgress::End(WorkDoneProgressEnd {
111                message: Some("Finished parsing".to_string()),
112            })),
113        })
114        .await;
115}
116*/