aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBlaž Hrastnik2021-08-16 04:59:02 +0000
committerBlaž Hrastnik2021-08-20 04:43:54 +0000
commit184abdc51061bd1636f31edcb51d71d0362a3d83 (patch)
tree92ae383359a6cf430e8e2c8a7bcbb756df41eb10
parent3a9e1c305b1ab080e77a2d6a405710fd1f20015e (diff)
dap: Significantly simplify code using the Request trait
-rw-r--r--helix-dap/examples/dap-dlv.rs6
-rw-r--r--helix-dap/examples/dap-lldb.rs6
-rw-r--r--helix-dap/src/client.rs87
-rw-r--r--helix-dap/src/types.rs45
4 files changed, 82 insertions, 62 deletions
diff --git a/helix-dap/examples/dap-dlv.rs b/helix-dap/examples/dap-dlv.rs
index a18ec5e2..352c2144 100644
--- a/helix-dap/examples/dap-dlv.rs
+++ b/helix-dap/examples/dap-dlv.rs
@@ -1,4 +1,4 @@
-use helix_dap::{Client, Event, OutputEventBody, Result, SourceBreakpoint, StoppedEventBody};
+use helix_dap::{events, Client, Event, Result, SourceBreakpoint};
use serde::{Deserialize, Serialize};
use serde_json::from_value;
use tokio::sync::mpsc::Receiver;
@@ -12,7 +12,7 @@ struct LaunchArguments {
async fn output(mut output_event: Receiver<Event>) {
loop {
- let body: OutputEventBody =
+ let body: events::Output =
from_value(output_event.recv().await.unwrap().body.unwrap()).unwrap();
println!(
"> [{}] {}",
@@ -77,7 +77,7 @@ pub async fn main() -> Result<()> {
println!("configurationDone: {:?}", client.configuration_done().await);
- let stop: StoppedEventBody =
+ let stop: events::Stopped =
from_value(stopped_event.recv().await.unwrap().body.unwrap()).unwrap();
println!("stopped: {:?}", stop);
diff --git a/helix-dap/examples/dap-lldb.rs b/helix-dap/examples/dap-lldb.rs
index 5e10ebed..85ff2762 100644
--- a/helix-dap/examples/dap-lldb.rs
+++ b/helix-dap/examples/dap-lldb.rs
@@ -1,4 +1,4 @@
-use helix_dap::{Client, Event, OutputEventBody, Result, SourceBreakpoint, StoppedEventBody};
+use helix_dap::{events, Client, Event, Result, SourceBreakpoint};
use serde::{Deserialize, Serialize};
use serde_json::from_value;
use tokio::sync::mpsc::Receiver;
@@ -12,7 +12,7 @@ struct LaunchArguments {
async fn output(mut output_event: Receiver<Event>) {
loop {
- let body: OutputEventBody =
+ let body: events::Output =
from_value(output_event.recv().await.unwrap().body.unwrap()).unwrap();
println!(
"> [{}] {}",
@@ -77,7 +77,7 @@ pub async fn main() -> Result<()> {
println!("configurationDone: {:?}", client.configuration_done().await);
- let stop: StoppedEventBody =
+ let stop: events::Stopped =
from_value(stopped_event.recv().await.unwrap().body.unwrap()).unwrap();
println!("stopped: {:?}", stop);
diff --git a/helix-dap/src/client.rs b/helix-dap/src/client.rs
index 5046159c..0f23dd15 100644
--- a/helix-dap/src/client.rs
+++ b/helix-dap/src/client.rs
@@ -1,11 +1,9 @@
use crate::{
- transport::{Event, Payload, Request, Response, Transport},
+ transport::{Event, Payload, Request, Transport},
types::*,
Result,
};
pub use log::{error, info};
-use serde::Serialize;
-use serde_json::{from_value, to_value, Value};
use std::{
collections::HashMap,
net::{IpAddr, Ipv4Addr},
@@ -184,13 +182,18 @@ impl Client {
self.request_counter.fetch_add(1, Ordering::Relaxed)
}
- async fn request(&self, command: String, arguments: Option<Value>) -> Result<Response> {
+ async fn request<R: crate::types::Request>(
+ &self,
+ arguments: R::Arguments,
+ ) -> Result<R::Result> {
let (callback_rx, mut callback_tx) = channel(1);
+ let arguments = Some(serde_json::to_value(arguments)?);
+
let req = Request {
back_ch: Some(callback_rx),
seq: self.next_request_id(),
- command,
+ command: R::COMMAND.to_string(),
arguments,
};
@@ -198,7 +201,9 @@ impl Client {
.send(req)
.expect("Failed to send request to debugger");
- Ok(callback_tx.recv().await.unwrap()?)
+ let response = callback_tx.recv().await.unwrap()?;
+ let response = serde_json::from_value(response.body.unwrap_or_default())?;
+ Ok(response)
}
pub fn capabilities(&self) -> &DebuggerCapabilities {
@@ -224,33 +229,30 @@ impl Client {
supports_invalidated_event: Some(false),
};
- let response = self
- .request("initialize".to_owned(), to_value(args).ok())
- .await?;
- self.capabilities = from_value(response.body.unwrap()).ok();
+ let response = self.request::<requests::Initialize>(args).await?;
+ self.capabilities = Some(response);
Ok(())
}
pub async fn disconnect(&mut self) -> Result<()> {
- self.request("disconnect".to_owned(), None).await?;
- Ok(())
+ self.request::<requests::Disconnect>(()).await
}
- pub async fn launch(&mut self, args: impl Serialize) -> Result<()> {
+ pub async fn launch(&mut self, args: serde_json::Value) -> Result<()> {
let mut initialized = self.listen_for_event("initialized".to_owned()).await;
- let res = self.request("launch".to_owned(), to_value(args).ok());
+ let res = self.request::<requests::Launch>(args);
let ev = initialized.recv();
join!(res, ev).0?;
Ok(())
}
- pub async fn attach(&mut self, args: impl Serialize) -> Result<()> {
+ pub async fn attach(&mut self, args: serde_json::Value) -> Result<()> {
let mut initialized = self.listen_for_event("initialized".to_owned()).await;
- let res = self.request("attach".to_owned(), to_value(args).ok());
+ let res = self.request::<requests::Attach>(args);
let ev = initialized.recv();
join!(res, ev).0?;
@@ -277,29 +279,20 @@ impl Client {
source_modified: Some(false),
};
- let response = self
- .request("setBreakpoints".to_owned(), to_value(args).ok())
- .await?;
- let body: Option<requests::SetBreakpointsResponse> = from_value(response.body.unwrap()).ok();
+ let response = self.request::<requests::SetBreakpoints>(args).await?;
- Ok(body.map(|b| b.breakpoints).unwrap())
+ Ok(response.breakpoints)
}
pub async fn configuration_done(&mut self) -> Result<()> {
- self.request("configurationDone".to_owned(), None).await?;
- Ok(())
+ self.request::<requests::ConfigurationDone>(()).await
}
pub async fn continue_thread(&mut self, thread_id: usize) -> Result<Option<bool>> {
let args = requests::ContinueArguments { thread_id };
- let response = self
- .request("continue".to_owned(), to_value(args).ok())
- .await?;
-
- let body: Option<requests::ContinueResponse> = from_value(response.body.unwrap()).ok();
-
- Ok(body.map(|b| b.all_threads_continued).unwrap())
+ let response = self.request::<requests::Continue>(args).await?;
+ Ok(response.all_threads_continued)
}
pub async fn stack_trace(
@@ -313,33 +306,20 @@ impl Client {
format: None,
};
- let response = self
- .request("stackTrace".to_owned(), to_value(args).ok())
- .await?;
-
- let body: requests::StackTraceResponse = from_value(response.body.unwrap()).unwrap();
-
- Ok((body.stack_frames, body.total_frames))
+ let response = self.request::<requests::StackTrace>(args).await?;
+ Ok((response.stack_frames, response.total_frames))
}
pub async fn threads(&mut self) -> Result<Vec<Thread>> {
- let response = self.request("threads".to_owned(), None).await?;
-
- let body: requests::ThreadsResponse = from_value(response.body.unwrap()).unwrap();
-
- Ok(body.threads)
+ let response = self.request::<requests::Threads>(()).await?;
+ Ok(response.threads)
}
pub async fn scopes(&mut self, frame_id: usize) -> Result<Vec<Scope>> {
let args = requests::ScopesArguments { frame_id };
- let response = self
- .request("scopes".to_owned(), to_value(args).ok())
- .await?;
-
- let body: requests::ScopesResponse = from_value(response.body.unwrap()).unwrap();
-
- Ok(body.scopes)
+ let response = self.request::<requests::Scopes>(args).await?;
+ Ok(response.scopes)
}
pub async fn variables(&mut self, variables_reference: usize) -> Result<Vec<Variable>> {
@@ -351,12 +331,7 @@ impl Client {
format: None,
};
- let response = self
- .request("variables".to_owned(), to_value(args).ok())
- .await?;
-
- let body: requests::VariablesResponse = from_value(response.body.unwrap()).unwrap();
-
- Ok(body.variables)
+ let response = self.request::<requests::Variables>(args).await?;
+ Ok(response.variables)
}
}
diff --git a/helix-dap/src/types.rs b/helix-dap/src/types.rs
index 3f7e3c43..d57c533d 100644
--- a/helix-dap/src/types.rs
+++ b/helix-dap/src/types.rs
@@ -229,6 +229,51 @@ pub mod requests {
pub supports_invalidated_event: Option<bool>,
}
+ #[derive(Debug)]
+ pub enum Initialize {}
+
+ impl Request for Initialize {
+ type Arguments = InitializeArguments;
+ type Result = DebuggerCapabilities;
+ const COMMAND: &'static str = "initialize";
+ }
+
+ #[derive(Debug)]
+ pub enum Launch {}
+
+ impl Request for Launch {
+ type Arguments = Value;
+ type Result = Value;
+ const COMMAND: &'static str = "launch";
+ }
+
+ #[derive(Debug)]
+ pub enum Attach {}
+
+ impl Request for Attach {
+ type Arguments = Value;
+ type Result = Value;
+ const COMMAND: &'static str = "attach";
+ }
+
+ #[derive(Debug)]
+ pub enum Disconnect {}
+
+ impl Request for Disconnect {
+ type Arguments = ();
+ type Result = ();
+ const COMMAND: &'static str = "disconnect";
+ }
+
+ #[derive(Debug)]
+ pub enum ConfigurationDone {}
+
+ impl Request for ConfigurationDone {
+ type Arguments = ();
+ type Result = ();
+ const COMMAND: &'static str = "configurationDone";
+ }
+
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SetBreakpointsArguments {