From 184abdc51061bd1636f31edcb51d71d0362a3d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Mon, 16 Aug 2021 13:59:02 +0900 Subject: [PATCH] dap: Significantly simplify code using the Request trait --- helix-dap/examples/dap-dlv.rs | 6 +-- helix-dap/examples/dap-lldb.rs | 6 +-- helix-dap/src/client.rs | 87 ++++++++++++---------------------- helix-dap/src/types.rs | 45 ++++++++++++++++++ 4 files changed, 82 insertions(+), 62 deletions(-) diff --git a/helix-dap/examples/dap-dlv.rs b/helix-dap/examples/dap-dlv.rs index a18ec5e2b..352c21444 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) { 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 5e10ebed5..85ff27625 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) { 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 5046159c6..0f23dd15a 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) -> Result { + async fn request( + &self, + arguments: R::Arguments, + ) -> 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::(args).await?; + self.capabilities = Some(response); Ok(()) } pub async fn disconnect(&mut self) -> Result<()> { - self.request("disconnect".to_owned(), None).await?; - Ok(()) + self.request::(()).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::(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::(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 = from_value(response.body.unwrap()).ok(); + let response = self.request::(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::(()).await } pub async fn continue_thread(&mut self, thread_id: usize) -> Result> { let args = requests::ContinueArguments { thread_id }; - let response = self - .request("continue".to_owned(), to_value(args).ok()) - .await?; - - let body: Option = from_value(response.body.unwrap()).ok(); - - Ok(body.map(|b| b.all_threads_continued).unwrap()) + let response = self.request::(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::(args).await?; + Ok((response.stack_frames, response.total_frames)) } pub async fn threads(&mut self) -> Result> { - 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::(()).await?; + Ok(response.threads) } pub async fn scopes(&mut self, frame_id: usize) -> Result> { 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::(args).await?; + Ok(response.scopes) } pub async fn variables(&mut self, variables_reference: usize) -> Result> { @@ -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::(args).await?; + Ok(response.variables) } } diff --git a/helix-dap/src/types.rs b/helix-dap/src/types.rs index 3f7e3c43b..d57c533dd 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, } + #[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 {