extension_dap_adapter.rs

 1use std::{path::PathBuf, sync::Arc};
 2
 3use anyhow::Result;
 4use async_trait::async_trait;
 5use dap::adapters::{
 6    DapDelegate, DebugAdapter, DebugAdapterBinary, DebugAdapterName, DebugTaskDefinition,
 7};
 8use extension::{Extension, WorktreeDelegate};
 9use gpui::AsyncApp;
10use task::{DebugScenario, ZedDebugConfig};
11
12pub(crate) struct ExtensionDapAdapter {
13    extension: Arc<dyn Extension>,
14    debug_adapter_name: Arc<str>,
15}
16
17impl ExtensionDapAdapter {
18    pub(crate) fn new(
19        extension: Arc<dyn extension::Extension>,
20        debug_adapter_name: Arc<str>,
21    ) -> Self {
22        Self {
23            extension,
24            debug_adapter_name,
25        }
26    }
27}
28
29/// An adapter that allows an [`dap::adapters::DapDelegate`] to be used as a [`WorktreeDelegate`].
30struct WorktreeDelegateAdapter(pub Arc<dyn DapDelegate>);
31
32#[async_trait]
33impl WorktreeDelegate for WorktreeDelegateAdapter {
34    fn id(&self) -> u64 {
35        self.0.worktree_id().to_proto()
36    }
37
38    fn root_path(&self) -> String {
39        self.0.worktree_root_path().to_string_lossy().to_string()
40    }
41
42    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
43        self.0.read_text_file(path).await
44    }
45
46    async fn which(&self, binary_name: String) -> Option<String> {
47        self.0
48            .which(binary_name.as_ref())
49            .await
50            .map(|path| path.to_string_lossy().to_string())
51    }
52
53    async fn shell_env(&self) -> Vec<(String, String)> {
54        self.0.shell_env().await.into_iter().collect()
55    }
56}
57
58#[async_trait(?Send)]
59impl DebugAdapter for ExtensionDapAdapter {
60    fn name(&self) -> DebugAdapterName {
61        self.debug_adapter_name.as_ref().into()
62    }
63
64    async fn dap_schema(&self) -> serde_json::Value {
65        self.extension.get_dap_schema().await.unwrap_or_default()
66    }
67
68    async fn get_binary(
69        &self,
70        delegate: &Arc<dyn DapDelegate>,
71        config: &DebugTaskDefinition,
72        user_installed_path: Option<PathBuf>,
73        _cx: &mut AsyncApp,
74    ) -> Result<DebugAdapterBinary> {
75        self.extension
76            .get_dap_binary(
77                self.debug_adapter_name.clone(),
78                config.clone(),
79                user_installed_path,
80                Arc::new(WorktreeDelegateAdapter(delegate.clone())),
81            )
82            .await
83    }
84
85    fn config_from_zed_format(&self, _zed_scenario: ZedDebugConfig) -> Result<DebugScenario> {
86        Err(anyhow::anyhow!("DAP extensions are not implemented yet"))
87    }
88}