1use gpui::AsyncApp;
2use std::{ffi::OsStr, path::PathBuf};
3use task::DebugTaskDefinition;
4
5use crate::*;
6
7#[derive(Default, Debug)]
8pub(crate) struct GoDebugAdapter;
9
10impl GoDebugAdapter {
11 const ADAPTER_NAME: &'static str = "Delve";
12}
13
14#[async_trait(?Send)]
15impl DebugAdapter for GoDebugAdapter {
16 fn name(&self) -> DebugAdapterName {
17 DebugAdapterName(Self::ADAPTER_NAME.into())
18 }
19
20 async fn get_binary(
21 &self,
22 delegate: &dyn DapDelegate,
23 config: &DebugAdapterConfig,
24 user_installed_path: Option<PathBuf>,
25 cx: &mut AsyncApp,
26 ) -> Result<DebugAdapterBinary> {
27 self.get_installed_binary(delegate, config, user_installed_path, cx)
28 .await
29 }
30
31 async fn fetch_latest_adapter_version(
32 &self,
33 _delegate: &dyn DapDelegate,
34 ) -> Result<AdapterVersion> {
35 unimplemented!("This adapter is used from path for now");
36 }
37
38 async fn install_binary(
39 &self,
40 version: AdapterVersion,
41 delegate: &dyn DapDelegate,
42 ) -> Result<()> {
43 adapters::download_adapter_from_github(
44 self.name(),
45 version,
46 adapters::DownloadedFileType::Zip,
47 delegate,
48 )
49 .await?;
50 Ok(())
51 }
52
53 async fn get_installed_binary(
54 &self,
55 delegate: &dyn DapDelegate,
56 config: &DebugAdapterConfig,
57 _: Option<PathBuf>,
58 _: &mut AsyncApp,
59 ) -> Result<DebugAdapterBinary> {
60 let delve_path = delegate
61 .which(OsStr::new("dlv"))
62 .and_then(|p| p.to_str().map(|p| p.to_string()))
63 .ok_or(anyhow!("Dlv not found in path"))?;
64
65 let tcp_connection = config.tcp_connection.clone().unwrap_or_default();
66 let (host, port, timeout) = crate::configure_tcp_connection(tcp_connection).await?;
67
68 Ok(DebugAdapterBinary {
69 command: delve_path,
70 arguments: Some(vec![
71 "dap".into(),
72 "--listen".into(),
73 format!("{}:{}", host, port).into(),
74 ]),
75 cwd: None,
76 envs: None,
77 connection: Some(adapters::TcpArguments {
78 host,
79 port,
80 timeout,
81 }),
82 })
83 }
84
85 fn request_args(&self, config: &DebugTaskDefinition) -> Value {
86 let mut args = match &config.request {
87 dap::DebugRequestType::Attach(attach_config) => {
88 json!({
89 "processId": attach_config.process_id,
90 })
91 }
92 dap::DebugRequestType::Launch(launch_config) => json!({
93 "program": launch_config.program,
94 "cwd": launch_config.cwd,
95 "args": launch_config.args
96 }),
97 };
98
99 let map = args.as_object_mut().unwrap();
100
101 if let Some(stop_on_entry) = config.stop_on_entry {
102 map.insert("stopOnEntry".into(), stop_on_entry.into());
103 }
104
105 args
106 }
107}