1use dap::{StartDebuggingRequestArguments, adapters::DebugTaskDefinition};
2use gpui::AsyncApp;
3use std::{collections::HashMap, ffi::OsStr, path::PathBuf};
4
5use crate::*;
6
7#[derive(Default, Debug)]
8pub(crate) struct GoDebugAdapter;
9
10impl GoDebugAdapter {
11 const ADAPTER_NAME: &'static str = "Delve";
12 fn request_args(&self, config: &DebugTaskDefinition) -> StartDebuggingRequestArguments {
13 let mut args = match &config.request {
14 dap::DebugRequest::Attach(attach_config) => {
15 json!({
16 "processId": attach_config.process_id,
17 })
18 }
19 dap::DebugRequest::Launch(launch_config) => json!({
20 "program": launch_config.program,
21 "cwd": launch_config.cwd,
22 "args": launch_config.args
23 }),
24 };
25
26 let map = args.as_object_mut().unwrap();
27
28 if let Some(stop_on_entry) = config.stop_on_entry {
29 map.insert("stopOnEntry".into(), stop_on_entry.into());
30 }
31
32 StartDebuggingRequestArguments {
33 configuration: args,
34 request: config.request.to_dap(),
35 }
36 }
37}
38
39#[async_trait(?Send)]
40impl DebugAdapter for GoDebugAdapter {
41 fn name(&self) -> DebugAdapterName {
42 DebugAdapterName(Self::ADAPTER_NAME.into())
43 }
44
45 async fn get_binary(
46 &self,
47 delegate: &dyn DapDelegate,
48 config: &DebugTaskDefinition,
49 _user_installed_path: Option<PathBuf>,
50 _cx: &mut AsyncApp,
51 ) -> Result<DebugAdapterBinary> {
52 let delve_path = delegate
53 .which(OsStr::new("dlv"))
54 .and_then(|p| p.to_str().map(|p| p.to_string()))
55 .ok_or(anyhow!("Dlv not found in path"))?;
56
57 let tcp_connection = config.tcp_connection.clone().unwrap_or_default();
58 let (host, port, timeout) = crate::configure_tcp_connection(tcp_connection).await?;
59
60 Ok(DebugAdapterBinary {
61 command: delve_path,
62 arguments: vec![
63 "dap".into(),
64 "--listen".into(),
65 format!("{}:{}", host, port),
66 ],
67 cwd: None,
68 envs: HashMap::default(),
69 connection: Some(adapters::TcpArguments {
70 host,
71 port,
72 timeout,
73 }),
74 request_args: self.request_args(config),
75 })
76 }
77}