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 self.get_installed_binary(delegate, config, user_installed_path, cx)
53 .await
54 }
55
56 async fn fetch_latest_adapter_version(
57 &self,
58 _delegate: &dyn DapDelegate,
59 ) -> Result<AdapterVersion> {
60 unimplemented!("This adapter is used from path for now");
61 }
62
63 async fn install_binary(
64 &self,
65 version: AdapterVersion,
66 delegate: &dyn DapDelegate,
67 ) -> Result<()> {
68 adapters::download_adapter_from_github(
69 self.name(),
70 version,
71 adapters::DownloadedFileType::Zip,
72 delegate,
73 )
74 .await?;
75 Ok(())
76 }
77
78 async fn get_installed_binary(
79 &self,
80 delegate: &dyn DapDelegate,
81 config: &DebugTaskDefinition,
82 _: Option<PathBuf>,
83 _: &mut AsyncApp,
84 ) -> Result<DebugAdapterBinary> {
85 let delve_path = delegate
86 .which(OsStr::new("dlv"))
87 .and_then(|p| p.to_str().map(|p| p.to_string()))
88 .ok_or(anyhow!("Dlv not found in path"))?;
89
90 let tcp_connection = config.tcp_connection.clone().unwrap_or_default();
91 let (host, port, timeout) = crate::configure_tcp_connection(tcp_connection).await?;
92
93 Ok(DebugAdapterBinary {
94 command: delve_path,
95 arguments: vec![
96 "dap".into(),
97 "--listen".into(),
98 format!("{}:{}", host, port),
99 ],
100 cwd: None,
101 envs: HashMap::default(),
102 connection: Some(adapters::TcpArguments {
103 host,
104 port,
105 timeout,
106 }),
107 request_args: self.request_args(config),
108 })
109 }
110}