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