Skip to content

Commit cb72d84

Browse files
handle results
1 parent 97fc042 commit cb72d84

File tree

8 files changed

+100
-78
lines changed

8 files changed

+100
-78
lines changed

crates/pg_base_db/src/path.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,3 @@ impl PgLspPath {
2020
}
2121
}
2222
}
23-

crates/pg_lsp/src/client/client_config_opts.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ use serde::Deserialize;
33
// TODO: Check that the Opts are correct (existed in server.rs)
44
#[derive(Deserialize)]
55
pub struct ClientConfigurationOptions {
6-
pub db_connection_string: Option<String>
7-
}
6+
pub db_connection_string: Option<String>,
7+
}

crates/pg_lsp/src/client/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1+
pub mod client_config_opts;
12
pub mod client_flags;
2-
pub mod client_config_opts;

crates/pg_lsp/src/debouncer.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
1-
pub(crate) struct SimpleTokioDebouncer<Args> {
1+
use std::{future::Future, pin::Pin};
2+
3+
type AsyncBlock = Pin<Box<dyn Future<Output = ()> + 'static + Send>>;
4+
5+
pub(crate) struct SimpleTokioDebouncer {
26
handle: tokio::task::JoinHandle<()>,
3-
tx: tokio::sync::mpsc::Sender<Args>,
7+
tx: tokio::sync::mpsc::Sender<AsyncBlock>,
48
}
59

6-
impl<Args> SimpleTokioDebouncer<Args> {
7-
pub fn new<F>(timeout: std::time::Duration, mut callback: F) -> Self
8-
where
9-
F: FnMut(Args) + Send + 'static,
10-
Args: Send + 'static,
11-
{
10+
impl SimpleTokioDebouncer {
11+
pub fn new(timeout: std::time::Duration) -> Self {
1212
let (tx, mut rx) = tokio::sync::mpsc::channel(100);
1313

1414
let handle = tokio::spawn(async move {
15-
let mut maybe_args: Option<Args> = None;
15+
let mut maybe_args: Option<AsyncBlock> = None;
1616
let mut instant = tokio::time::Instant::now() + timeout;
1717

1818
loop {
1919
tokio::select! {
2020
// If the timeout is reached, execute and reset the last received action
2121
_ = tokio::time::sleep_until(instant) => {
2222
match maybe_args {
23-
Some(args) => {
24-
callback(args);
23+
Some(block) => {
24+
block.await;
2525
maybe_args = None;
2626
}
2727
None => continue,
@@ -45,9 +45,8 @@ impl<Args> SimpleTokioDebouncer<Args> {
4545
Self { handle, tx }
4646
}
4747

48-
pub async fn debounce(&self, args: Args)
49-
{
50-
self.tx.send(args).await.unwrap();
48+
pub async fn debounce(&self, block: AsyncBlock) {
49+
self.tx.send(block).await.unwrap();
5150
}
5251

5352
pub async fn shutdown(self) {

crates/pg_lsp/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
mod client;
22
mod db_connection;
33
mod debouncer;
4-
mod utils;
5-
mod session;
64
pub mod server;
5+
mod session;
6+
mod utils;

crates/pg_lsp/src/main.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@ use tower_lsp::LspService;
33

44
#[tokio::main]
55
async fn main() -> anyhow::Result<()> {
6-
let (server, client_socket) = LspService::build(|client| {
7-
Server::new(client)
8-
}).finish();
9-
6+
let (server, client_socket) = LspService::build(|client| Server::new(client)).finish();
107

118
Ok(())
129
}

crates/pg_lsp/src/server.rs

Lines changed: 71 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -17,52 +17,21 @@ pub struct Server {
1717
client: Client,
1818
session: Session,
1919
client_capabilities: RwLock<Option<ClientFlags>>,
20-
debouncer: SimpleTokioDebouncer<Url>,
20+
debouncer: SimpleTokioDebouncer,
2121
}
2222

2323
impl Server {
2424
pub fn new(client: Client) -> Self {
25-
let session = Session::new();
26-
27-
let cloned_session = session.clone();
28-
let cloned_client = client.clone();
29-
30-
let debouncer =
31-
SimpleTokioDebouncer::new(std::time::Duration::from_millis(500), move |mut uri| {
32-
normalize_uri(&mut uri);
33-
let url = file_path(&uri);
34-
35-
let diagnostics = cloned_session.get_diagnostics_sync(url);
36-
37-
let diagnostics: Vec<Diagnostic> = diagnostics
38-
.into_iter()
39-
.map(|(d, r)| to_proto::diagnostic(d, r))
40-
.collect();
41-
42-
cloned_client.send_notification::<ShowMessage>(ShowMessageParams {
43-
typ: MessageType::INFO,
44-
message: format!("diagnostics {}", diagnostics.len()),
45-
});
46-
47-
let params = PublishDiagnosticsParams {
48-
uri,
49-
diagnostics,
50-
version: None,
51-
};
52-
53-
cloned_client.send_notification::<notification::PublishDiagnostics>(params);
54-
});
55-
5625
Self {
5726
client,
5827
session: Session::new(),
5928
client_capabilities: RwLock::new(None),
60-
debouncer,
29+
debouncer: SimpleTokioDebouncer::new(std::time::Duration::from_millis(500)),
6130
}
6231
}
6332

6433
/// When the client sends a didChangeConfiguration notification, we need to parse the received JSON.
65-
fn parse_options_from_client(
34+
async fn parse_options_from_client(
6635
&self,
6736
mut value: serde_json::Value,
6837
) -> Option<ClientConfigurationOptions> {
@@ -79,7 +48,8 @@ impl Server {
7948
);
8049
let typ = MessageType::WARNING;
8150
self.client
82-
.send_notification::<ShowMessage>(ShowMessageParams { message, typ });
51+
.send_notification::<ShowMessage>(ShowMessageParams { message, typ })
52+
.await;
8353
None
8454
}
8555
}
@@ -106,17 +76,15 @@ impl Server {
10676
.next()
10777
.expect("workspace/configuration request did not yield expected response.");
10878

109-
let opts = self.parse_options_from_client(relevant);
110-
111-
opts
79+
self.parse_options_from_client(relevant).await
11280
}
11381
Err(why) => {
11482
let message = format!(
11583
"Unable to pull client options via workspace/configuration request: {}",
11684
why
11785
);
11886
println!("{}", message);
119-
self.client.log_message(MessageType::ERROR, message);
87+
self.client.log_message(MessageType::ERROR, message).await;
12088
None
12189
}
12290
}
@@ -137,7 +105,8 @@ impl Server {
137105
.send_notification::<ShowMessage>(ShowMessageParams {
138106
typ: MessageType::INFO,
139107
message: format!("diagnostics {}", diagnostics.len()),
140-
});
108+
})
109+
.await;
141110

142111
let params = PublishDiagnosticsParams {
143112
uri,
@@ -146,11 +115,44 @@ impl Server {
146115
};
147116

148117
self.client
149-
.send_notification::<notification::PublishDiagnostics>(params);
118+
.send_notification::<notification::PublishDiagnostics>(params)
119+
.await;
150120
}
151121

152-
async fn publish_diagnostics_debounced(&self, uri: Url) {
153-
self.debouncer.debounce(uri);
122+
async fn publish_diagnostics_debounced(&self, mut uri: Url) {
123+
let session = self.session.clone();
124+
let client = self.client.clone();
125+
126+
self.debouncer
127+
.debounce(Box::pin(async move {
128+
normalize_uri(&mut uri);
129+
let url = file_path(&uri);
130+
131+
let diagnostics = session.get_diagnostics_sync(url);
132+
133+
let diagnostics: Vec<Diagnostic> = diagnostics
134+
.into_iter()
135+
.map(|(d, r)| to_proto::diagnostic(d, r))
136+
.collect();
137+
138+
client
139+
.send_notification::<ShowMessage>(ShowMessageParams {
140+
typ: MessageType::INFO,
141+
message: format!("diagnostics {}", diagnostics.len()),
142+
})
143+
.await;
144+
145+
let params = PublishDiagnosticsParams {
146+
uri,
147+
diagnostics,
148+
version: None,
149+
};
150+
151+
client
152+
.send_notification::<notification::PublishDiagnostics>(params)
153+
.await;
154+
}))
155+
.await;
154156
}
155157
}
156158

@@ -197,6 +199,8 @@ impl LanguageServer for Server {
197199
}
198200

199201
async fn shutdown(&self) -> jsonrpc::Result<()> {
202+
// TODO: Shutdown stuff.
203+
200204
self.client
201205
.log_message(MessageType::INFO, "Postgres LSP terminated.")
202206
.await;
@@ -213,21 +217,41 @@ impl LanguageServer for Server {
213217
.is_some_and(|o| o.db_connection_string.is_some())
214218
{
215219
let conn_str = opts.unwrap().db_connection_string.unwrap();
216-
self.session.change_db(conn_str).await;
220+
match self.session.change_db(conn_str).await {
221+
Ok(_) => {}
222+
Err(err) => {
223+
self.client
224+
.show_message(
225+
MessageType::ERROR,
226+
format!("Pulled Client Options but failed to set them: {}", err),
227+
)
228+
.await
229+
}
230+
}
217231
return;
218232
}
219233
}
220234

221235
// if we couldn't pull settings from the client,
222236
// we'll try parsing the passed in params.
223-
let opts = self.parse_options_from_client(params.settings);
237+
let opts = self.parse_options_from_client(params.settings).await;
224238

225239
if opts
226240
.as_ref()
227241
.is_some_and(|o| o.db_connection_string.is_some())
228242
{
229243
let conn_str = opts.unwrap().db_connection_string.unwrap();
230-
self.session.change_db(conn_str).await;
244+
match self.session.change_db(conn_str).await {
245+
Ok(_) => {}
246+
Err(err) => {
247+
self.client
248+
.show_message(
249+
MessageType::ERROR,
250+
format!("Used Client Options from params but failed to set them: {}", err),
251+
)
252+
.await
253+
}
254+
}
231255
}
232256
}
233257

@@ -268,7 +292,7 @@ impl LanguageServer for Server {
268292
let mut uri = params.text_document.uri;
269293
normalize_uri(&mut uri);
270294

271-
self.debouncer.debounce(uri).await
295+
self.publish_diagnostics_debounced(uri).await;
272296
}
273297

274298
async fn did_close(&self, params: DidCloseTextDocumentParams) {

crates/pg_lsp/src/session.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{collections::HashSet,sync::Arc};
1+
use std::{collections::HashSet, sync::Arc};
22

33
use pg_base_db::{Change, DocumentChange, PgLspPath};
44
use pg_commands::{Command, ExecuteStatementCommand};
@@ -9,7 +9,8 @@ use pg_workspace::Workspace;
99
use text_size::TextSize;
1010
use tokio::sync::RwLock;
1111
use tower_lsp::lsp_types::{
12-
CodeActionOrCommand, CompletionItem, CompletionItemKind, CompletionList, Hover, HoverContents, InlayHint, InlayHintKind, InlayHintLabel, MarkedString, Position, Range
12+
CodeActionOrCommand, CompletionItem, CompletionItemKind, CompletionList, Hover, HoverContents,
13+
InlayHint, InlayHintKind, InlayHintLabel, MarkedString, Position, Range,
1314
};
1415

1516
use crate::{db_connection::DbConnection, utils::line_index_ext::LineIndexExt};
@@ -29,6 +30,10 @@ impl Session {
2930
}
3031
}
3132

33+
async fn shutdown(&mut self) {
34+
// TODO
35+
}
36+
3237
/// `update_db_connection` will update `Self`'s database connection.
3338
/// If the passed-in connection string is the same that we're already connected to, it's a noop.
3439
/// Otherwise, it'll first open a new connection, replace `Self`'s connection, and then close
@@ -50,7 +55,8 @@ impl Session {
5055
let ide = self.ide.clone();
5156
db.listen_for_schema_updates(move |schema| {
5257
let _guard = ide.blocking_write().set_schema_cache(schema);
53-
});
58+
})
59+
.await?;
5460

5561
let mut current_db = self.db.blocking_write();
5662
let old_db = current_db.replace(db);
@@ -160,10 +166,7 @@ impl Session {
160166

161167
let changed_files = ide.compute(pool);
162168

163-
changed_files
164-
.into_iter()
165-
.map(|p| p.document_url)
166-
.collect()
169+
changed_files.into_iter().map(|p| p.document_url).collect()
167170
}
168171

169172
pub async fn get_available_code_actions_or_commands(

0 commit comments

Comments
 (0)