mirror of
https://github.com/helix-editor/helix.git
synced 2025-04-04 11:27:46 +03:00
dap: Significantly simplify code using the Request trait
This commit is contained in:
parent
3a9e1c305b
commit
184abdc510
4 changed files with 82 additions and 62 deletions
|
@ -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::{Deserialize, Serialize};
|
||||||
use serde_json::from_value;
|
use serde_json::from_value;
|
||||||
use tokio::sync::mpsc::Receiver;
|
use tokio::sync::mpsc::Receiver;
|
||||||
|
@ -12,7 +12,7 @@ struct LaunchArguments {
|
||||||
|
|
||||||
async fn output(mut output_event: Receiver<Event>) {
|
async fn output(mut output_event: Receiver<Event>) {
|
||||||
loop {
|
loop {
|
||||||
let body: OutputEventBody =
|
let body: events::Output =
|
||||||
from_value(output_event.recv().await.unwrap().body.unwrap()).unwrap();
|
from_value(output_event.recv().await.unwrap().body.unwrap()).unwrap();
|
||||||
println!(
|
println!(
|
||||||
"> [{}] {}",
|
"> [{}] {}",
|
||||||
|
@ -77,7 +77,7 @@ pub async fn main() -> Result<()> {
|
||||||
|
|
||||||
println!("configurationDone: {:?}", client.configuration_done().await);
|
println!("configurationDone: {:?}", client.configuration_done().await);
|
||||||
|
|
||||||
let stop: StoppedEventBody =
|
let stop: events::Stopped =
|
||||||
from_value(stopped_event.recv().await.unwrap().body.unwrap()).unwrap();
|
from_value(stopped_event.recv().await.unwrap().body.unwrap()).unwrap();
|
||||||
println!("stopped: {:?}", stop);
|
println!("stopped: {:?}", stop);
|
||||||
|
|
||||||
|
|
|
@ -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::{Deserialize, Serialize};
|
||||||
use serde_json::from_value;
|
use serde_json::from_value;
|
||||||
use tokio::sync::mpsc::Receiver;
|
use tokio::sync::mpsc::Receiver;
|
||||||
|
@ -12,7 +12,7 @@ struct LaunchArguments {
|
||||||
|
|
||||||
async fn output(mut output_event: Receiver<Event>) {
|
async fn output(mut output_event: Receiver<Event>) {
|
||||||
loop {
|
loop {
|
||||||
let body: OutputEventBody =
|
let body: events::Output =
|
||||||
from_value(output_event.recv().await.unwrap().body.unwrap()).unwrap();
|
from_value(output_event.recv().await.unwrap().body.unwrap()).unwrap();
|
||||||
println!(
|
println!(
|
||||||
"> [{}] {}",
|
"> [{}] {}",
|
||||||
|
@ -77,7 +77,7 @@ pub async fn main() -> Result<()> {
|
||||||
|
|
||||||
println!("configurationDone: {:?}", client.configuration_done().await);
|
println!("configurationDone: {:?}", client.configuration_done().await);
|
||||||
|
|
||||||
let stop: StoppedEventBody =
|
let stop: events::Stopped =
|
||||||
from_value(stopped_event.recv().await.unwrap().body.unwrap()).unwrap();
|
from_value(stopped_event.recv().await.unwrap().body.unwrap()).unwrap();
|
||||||
println!("stopped: {:?}", stop);
|
println!("stopped: {:?}", stop);
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
transport::{Event, Payload, Request, Response, Transport},
|
transport::{Event, Payload, Request, Transport},
|
||||||
types::*,
|
types::*,
|
||||||
Result,
|
Result,
|
||||||
};
|
};
|
||||||
pub use log::{error, info};
|
pub use log::{error, info};
|
||||||
use serde::Serialize;
|
|
||||||
use serde_json::{from_value, to_value, Value};
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
net::{IpAddr, Ipv4Addr},
|
net::{IpAddr, Ipv4Addr},
|
||||||
|
@ -184,13 +182,18 @@ impl Client {
|
||||||
self.request_counter.fetch_add(1, Ordering::Relaxed)
|
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 (callback_rx, mut callback_tx) = channel(1);
|
||||||
|
|
||||||
|
let arguments = Some(serde_json::to_value(arguments)?);
|
||||||
|
|
||||||
let req = Request {
|
let req = Request {
|
||||||
back_ch: Some(callback_rx),
|
back_ch: Some(callback_rx),
|
||||||
seq: self.next_request_id(),
|
seq: self.next_request_id(),
|
||||||
command,
|
command: R::COMMAND.to_string(),
|
||||||
arguments,
|
arguments,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -198,7 +201,9 @@ impl Client {
|
||||||
.send(req)
|
.send(req)
|
||||||
.expect("Failed to send request to debugger");
|
.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 {
|
pub fn capabilities(&self) -> &DebuggerCapabilities {
|
||||||
|
@ -224,33 +229,30 @@ impl Client {
|
||||||
supports_invalidated_event: Some(false),
|
supports_invalidated_event: Some(false),
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = self
|
let response = self.request::<requests::Initialize>(args).await?;
|
||||||
.request("initialize".to_owned(), to_value(args).ok())
|
self.capabilities = Some(response);
|
||||||
.await?;
|
|
||||||
self.capabilities = from_value(response.body.unwrap()).ok();
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn disconnect(&mut self) -> Result<()> {
|
pub async fn disconnect(&mut self) -> Result<()> {
|
||||||
self.request("disconnect".to_owned(), None).await?;
|
self.request::<requests::Disconnect>(()).await
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 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();
|
let ev = initialized.recv();
|
||||||
join!(res, ev).0?;
|
join!(res, ev).0?;
|
||||||
|
|
||||||
Ok(())
|
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 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();
|
let ev = initialized.recv();
|
||||||
join!(res, ev).0?;
|
join!(res, ev).0?;
|
||||||
|
|
||||||
|
@ -277,29 +279,20 @@ impl Client {
|
||||||
source_modified: Some(false),
|
source_modified: Some(false),
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = self
|
let response = self.request::<requests::SetBreakpoints>(args).await?;
|
||||||
.request("setBreakpoints".to_owned(), to_value(args).ok())
|
|
||||||
.await?;
|
|
||||||
let body: Option<requests::SetBreakpointsResponse> = from_value(response.body.unwrap()).ok();
|
|
||||||
|
|
||||||
Ok(body.map(|b| b.breakpoints).unwrap())
|
Ok(response.breakpoints)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn configuration_done(&mut self) -> Result<()> {
|
pub async fn configuration_done(&mut self) -> Result<()> {
|
||||||
self.request("configurationDone".to_owned(), None).await?;
|
self.request::<requests::ConfigurationDone>(()).await
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn continue_thread(&mut self, thread_id: usize) -> Result<Option<bool>> {
|
pub async fn continue_thread(&mut self, thread_id: usize) -> Result<Option<bool>> {
|
||||||
let args = requests::ContinueArguments { thread_id };
|
let args = requests::ContinueArguments { thread_id };
|
||||||
|
|
||||||
let response = self
|
let response = self.request::<requests::Continue>(args).await?;
|
||||||
.request("continue".to_owned(), to_value(args).ok())
|
Ok(response.all_threads_continued)
|
||||||
.await?;
|
|
||||||
|
|
||||||
let body: Option<requests::ContinueResponse> = from_value(response.body.unwrap()).ok();
|
|
||||||
|
|
||||||
Ok(body.map(|b| b.all_threads_continued).unwrap())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn stack_trace(
|
pub async fn stack_trace(
|
||||||
|
@ -313,33 +306,20 @@ impl Client {
|
||||||
format: None,
|
format: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = self
|
let response = self.request::<requests::StackTrace>(args).await?;
|
||||||
.request("stackTrace".to_owned(), to_value(args).ok())
|
Ok((response.stack_frames, response.total_frames))
|
||||||
.await?;
|
|
||||||
|
|
||||||
let body: requests::StackTraceResponse = from_value(response.body.unwrap()).unwrap();
|
|
||||||
|
|
||||||
Ok((body.stack_frames, body.total_frames))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn threads(&mut self) -> Result<Vec<Thread>> {
|
pub async fn threads(&mut self) -> Result<Vec<Thread>> {
|
||||||
let response = self.request("threads".to_owned(), None).await?;
|
let response = self.request::<requests::Threads>(()).await?;
|
||||||
|
Ok(response.threads)
|
||||||
let body: requests::ThreadsResponse = from_value(response.body.unwrap()).unwrap();
|
|
||||||
|
|
||||||
Ok(body.threads)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn scopes(&mut self, frame_id: usize) -> Result<Vec<Scope>> {
|
pub async fn scopes(&mut self, frame_id: usize) -> Result<Vec<Scope>> {
|
||||||
let args = requests::ScopesArguments { frame_id };
|
let args = requests::ScopesArguments { frame_id };
|
||||||
|
|
||||||
let response = self
|
let response = self.request::<requests::Scopes>(args).await?;
|
||||||
.request("scopes".to_owned(), to_value(args).ok())
|
Ok(response.scopes)
|
||||||
.await?;
|
|
||||||
|
|
||||||
let body: requests::ScopesResponse = from_value(response.body.unwrap()).unwrap();
|
|
||||||
|
|
||||||
Ok(body.scopes)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn variables(&mut self, variables_reference: usize) -> Result<Vec<Variable>> {
|
pub async fn variables(&mut self, variables_reference: usize) -> Result<Vec<Variable>> {
|
||||||
|
@ -351,12 +331,7 @@ impl Client {
|
||||||
format: None,
|
format: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = self
|
let response = self.request::<requests::Variables>(args).await?;
|
||||||
.request("variables".to_owned(), to_value(args).ok())
|
Ok(response.variables)
|
||||||
.await?;
|
|
||||||
|
|
||||||
let body: requests::VariablesResponse = from_value(response.body.unwrap()).unwrap();
|
|
||||||
|
|
||||||
Ok(body.variables)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,6 +229,51 @@ pub mod requests {
|
||||||
pub supports_invalidated_event: Option<bool>,
|
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)]
|
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct SetBreakpointsArguments {
|
pub struct SetBreakpointsArguments {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue