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;
10
11pub(crate) struct ExtensionDapAdapter {
12    extension: Arc<dyn Extension>,
13    debug_adapter_name: Arc<str>,
14}
15
16impl ExtensionDapAdapter {
17    pub(crate) fn new(
18        extension: Arc<dyn extension::Extension>,
19        debug_adapter_name: Arc<str>,
20    ) -> Self {
21        Self {
22            extension,
23            debug_adapter_name,
24        }
25    }
26}
27
28/// An adapter that allows an [`dap::adapters::DapDelegate`] to be used as a [`WorktreeDelegate`].
29struct WorktreeDelegateAdapter(pub Arc<dyn DapDelegate>);
30
31#[async_trait]
32impl WorktreeDelegate for WorktreeDelegateAdapter {
33    fn id(&self) -> u64 {
34        self.0.worktree_id().to_proto()
35    }
36
37    fn root_path(&self) -> String {
38        self.0.worktree_root_path().to_string_lossy().to_string()
39    }
40
41    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
42        self.0.read_text_file(path).await
43    }
44
45    async fn which(&self, binary_name: String) -> Option<String> {
46        self.0
47            .which(binary_name.as_ref())
48            .await
49            .map(|path| path.to_string_lossy().to_string())
50    }
51
52    async fn shell_env(&self) -> Vec<(String, String)> {
53        self.0.shell_env().await.into_iter().collect()
54    }
55}
56
57#[async_trait(?Send)]
58impl DebugAdapter for ExtensionDapAdapter {
59    fn name(&self) -> DebugAdapterName {
60        self.debug_adapter_name.as_ref().into()
61    }
62
63    async fn get_binary(
64        &self,
65        delegate: &Arc<dyn DapDelegate>,
66        config: &DebugTaskDefinition,
67        user_installed_path: Option<PathBuf>,
68        _cx: &mut AsyncApp,
69    ) -> Result<DebugAdapterBinary> {
70        self.extension
71            .get_dap_binary(
72                self.debug_adapter_name.clone(),
73                config.clone(),
74                user_installed_path,
75                Arc::new(WorktreeDelegateAdapter(delegate.clone())),
76            )
77            .await
78    }
79}