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