lspkit_server/
progress.rs1use std::sync::Arc;
8
9use async_trait::async_trait;
10
11#[non_exhaustive]
13#[derive(Debug, Clone)]
14pub struct ProgressUpdate {
15 pub token: String,
17 pub message: String,
19 pub percentage: Option<u32>,
21 pub done: bool,
23}
24
25impl ProgressUpdate {
26 #[must_use]
28 pub fn new(
29 token: impl Into<String>,
30 message: impl Into<String>,
31 percentage: Option<u32>,
32 ) -> Self {
33 Self {
34 token: token.into(),
35 message: message.into(),
36 percentage,
37 done: false,
38 }
39 }
40
41 #[must_use]
43 pub fn final_update(token: impl Into<String>, message: impl Into<String>) -> Self {
44 Self {
45 token: token.into(),
46 message: message.into(),
47 percentage: Some(100),
48 done: true,
49 }
50 }
51}
52
53#[async_trait]
55pub trait ProgressReporter: Send + Sync + 'static {
56 async fn report(&self, update: ProgressUpdate);
58}
59
60#[derive(Debug, Default, Clone, Copy)]
62pub struct NoopReporter;
63
64#[async_trait]
65impl ProgressReporter for NoopReporter {
66 async fn report(&self, _update: ProgressUpdate) {}
67}
68
69#[derive(Clone)]
71pub struct ProgressSink {
72 inner: Arc<dyn ProgressReporter>,
73 token: String,
74}
75
76impl ProgressSink {
77 pub fn new(inner: Arc<dyn ProgressReporter>, token: impl Into<String>) -> Self {
79 Self {
80 inner,
81 token: token.into(),
82 }
83 }
84
85 #[must_use]
87 pub fn noop() -> Self {
88 Self {
89 inner: Arc::new(NoopReporter),
90 token: String::new(),
91 }
92 }
93
94 pub async fn report(&self, message: impl Into<String>, percentage: Option<u32>) {
96 self.inner
97 .report(ProgressUpdate {
98 token: self.token.clone(),
99 message: message.into(),
100 percentage,
101 done: false,
102 })
103 .await;
104 }
105
106 pub async fn finish(&self, message: impl Into<String>) {
108 self.inner
109 .report(ProgressUpdate {
110 token: self.token.clone(),
111 message: message.into(),
112 percentage: Some(100),
113 done: true,
114 })
115 .await;
116 }
117}
118
119impl std::fmt::Debug for ProgressSink {
120 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
121 f.debug_struct("ProgressSink")
122 .field("token", &self.token)
123 .finish_non_exhaustive()
124 }
125}