aboutsummaryrefslogtreecommitdiff
path: root/helix-dap
diff options
context:
space:
mode:
authorBlaž Hrastnik2021-12-03 03:41:07 +0000
committerBlaž Hrastnik2021-12-03 03:41:07 +0000
commit032aaffa153e534481385af3b9fd3b8217d2e253 (patch)
tree9c59763f1b10795ad77a7558285e4f5ca9134bee /helix-dap
parent2dbf966293c7a92bd5eb6062c7033a20a207609f (diff)
dap: Split call/request in the same way LSP does
Diffstat (limited to 'helix-dap')
-rw-r--r--helix-dap/src/client.rs74
1 files changed, 50 insertions, 24 deletions
diff --git a/helix-dap/src/client.rs b/helix-dap/src/client.rs
index d83f25a6..09b4eaa1 100644
--- a/helix-dap/src/client.rs
+++ b/helix-dap/src/client.rs
@@ -5,10 +5,13 @@ use crate::{
};
use helix_core::syntax::DebuggerQuirks;
+use serde_json::Value;
+
use anyhow::anyhow;
pub use log::{error, info};
use std::{
collections::HashMap,
+ future::Future,
net::{IpAddr, Ipv4Addr, SocketAddr},
path::PathBuf,
process::Stdio,
@@ -205,27 +208,52 @@ impl Client {
self.request_counter.fetch_add(1, Ordering::Relaxed)
}
- async fn request<R: crate::types::Request>(
+ /// Execute a RPC request on the debugger.
+ fn call<R: crate::types::Request>(
&self,
arguments: R::Arguments,
- ) -> Result<R::Result> {
- let (callback_tx, mut callback_rx) = channel(1);
-
- let arguments = Some(serde_json::to_value(arguments)?);
-
- let req = Request {
- back_ch: Some(callback_tx),
- seq: self.next_request_id(),
- command: R::COMMAND.to_string(),
- arguments,
- };
-
- self.server_tx
- .send(req)
- .expect("Failed to send request to debugger");
+ ) -> impl Future<Output = Result<Value>>
+ where
+ R::Arguments: serde::Serialize,
+ {
+ let server_tx = self.server_tx.clone();
+ let id = self.next_request_id();
+
+ async move {
+ use std::time::Duration;
+ use tokio::time::timeout;
+
+ let arguments = Some(serde_json::to_value(arguments)?);
+
+ let (callback_tx, mut callback_rx) = channel(1);
+
+ let req = Request {
+ back_ch: Some(callback_tx),
+ seq: id,
+ command: R::COMMAND.to_string(),
+ arguments,
+ };
+
+ server_tx.send(req).map_err(|e| Error::Other(e.into()))?;
+
+ // TODO: specifiable timeout, delay other calls until initialize success
+ timeout(Duration::from_secs(20), callback_rx.recv())
+ .await
+ .map_err(|_| Error::Timeout)? // return Timeout
+ .ok_or(Error::StreamClosed)?
+ .map(|response| response.body.unwrap_or_default())
+ // TODO: check response.success
+ }
+ }
- let response = callback_rx.recv().await.unwrap()?;
- let response = serde_json::from_value(response.body.unwrap_or_default())?;
+ async fn request<R: crate::types::Request>(&self, params: R::Arguments) -> Result<R::Result>
+ where
+ R::Arguments: serde::Serialize,
+ R::Result: core::fmt::Debug, // TODO: temporary
+ {
+ // a future that resolves into the response
+ let json = self.call::<R>(params).await?;
+ let response = serde_json::from_value(json)?;
Ok(response)
}
@@ -260,18 +288,16 @@ impl Client {
self.request::<requests::Disconnect>(()).await
}
- pub async fn launch(&mut self, args: serde_json::Value) -> Result<()> {
+ pub async fn launch(&mut self, args: serde_json::Value) -> Result<Value> {
let response = self.request::<requests::Launch>(args).await?;
log::error!("launch response {}", response);
-
- Ok(())
+ Ok(response)
}
- pub async fn attach(&mut self, args: serde_json::Value) -> Result<()> {
+ pub async fn attach(&mut self, args: serde_json::Value) -> Result<Value> {
let response = self.request::<requests::Attach>(args).await?;
log::error!("attach response {}", response);
-
- Ok(())
+ Ok(response)
}
pub async fn set_breakpoints(