1use super::latest;
2use crate::wasm_host::WasmState;
3use anyhow::Result;
4use extension::WorktreeDelegate;
5use gpui::BackgroundExecutor;
6use semantic_version::SemanticVersion;
7use std::sync::{Arc, OnceLock};
8use wasmtime::component::{Linker, Resource};
9
10pub const MIN_VERSION: SemanticVersion = SemanticVersion::new(0, 0, 4);
11
12wasmtime::component::bindgen!({
13 async: true,
14 trappable_imports: true,
15 path: "../extension_api/wit/since_v0.0.4",
16 with: {
17 "worktree": ExtensionWorktree,
18 "zed:extension/github": latest::zed::extension::github,
19 "zed:extension/platform": latest::zed::extension::platform,
20 },
21});
22
23pub type ExtensionWorktree = Arc<dyn WorktreeDelegate>;
24
25pub fn linker(executor: &BackgroundExecutor) -> &'static Linker<WasmState> {
26 static LINKER: OnceLock<Linker<WasmState>> = OnceLock::new();
27 LINKER.get_or_init(|| super::new_linker(executor, Extension::add_to_linker))
28}
29
30impl From<DownloadedFileType> for latest::DownloadedFileType {
31 fn from(value: DownloadedFileType) -> Self {
32 match value {
33 DownloadedFileType::Gzip => latest::DownloadedFileType::Gzip,
34 DownloadedFileType::GzipTar => latest::DownloadedFileType::GzipTar,
35 DownloadedFileType::Zip => latest::DownloadedFileType::Zip,
36 DownloadedFileType::Uncompressed => latest::DownloadedFileType::Uncompressed,
37 }
38 }
39}
40
41impl From<LanguageServerInstallationStatus> for latest::LanguageServerInstallationStatus {
42 fn from(value: LanguageServerInstallationStatus) -> Self {
43 match value {
44 LanguageServerInstallationStatus::None => {
45 latest::LanguageServerInstallationStatus::None
46 }
47 LanguageServerInstallationStatus::Downloading => {
48 latest::LanguageServerInstallationStatus::Downloading
49 }
50 LanguageServerInstallationStatus::CheckingForUpdate => {
51 latest::LanguageServerInstallationStatus::CheckingForUpdate
52 }
53 LanguageServerInstallationStatus::Failed(error) => {
54 latest::LanguageServerInstallationStatus::Failed(error)
55 }
56 }
57 }
58}
59
60impl From<Command> for latest::Command {
61 fn from(value: Command) -> Self {
62 Self {
63 command: value.command,
64 args: value.args,
65 env: value.env,
66 }
67 }
68}
69
70impl HostWorktree for WasmState {
71 async fn read_text_file(
72 &mut self,
73 delegate: Resource<Arc<dyn WorktreeDelegate>>,
74 path: String,
75 ) -> wasmtime::Result<Result<String, String>> {
76 latest::HostWorktree::read_text_file(self, delegate, path).await
77 }
78
79 async fn shell_env(
80 &mut self,
81 delegate: Resource<Arc<dyn WorktreeDelegate>>,
82 ) -> wasmtime::Result<EnvVars> {
83 latest::HostWorktree::shell_env(self, delegate).await
84 }
85
86 async fn which(
87 &mut self,
88 delegate: Resource<Arc<dyn WorktreeDelegate>>,
89 binary_name: String,
90 ) -> wasmtime::Result<Option<String>> {
91 latest::HostWorktree::which(self, delegate, binary_name).await
92 }
93
94 async fn drop(&mut self, _worktree: Resource<Worktree>) -> Result<()> {
95 // We only ever hand out borrows of worktrees.
96 Ok(())
97 }
98}
99
100impl ExtensionImports for WasmState {
101 async fn node_binary_path(&mut self) -> wasmtime::Result<Result<String, String>> {
102 latest::nodejs::Host::node_binary_path(self).await
103 }
104
105 async fn npm_package_latest_version(
106 &mut self,
107 package_name: String,
108 ) -> wasmtime::Result<Result<String, String>> {
109 latest::nodejs::Host::npm_package_latest_version(self, package_name).await
110 }
111
112 async fn npm_package_installed_version(
113 &mut self,
114 package_name: String,
115 ) -> wasmtime::Result<Result<Option<String>, String>> {
116 latest::nodejs::Host::npm_package_installed_version(self, package_name).await
117 }
118
119 async fn npm_install_package(
120 &mut self,
121 package_name: String,
122 version: String,
123 ) -> wasmtime::Result<Result<(), String>> {
124 latest::nodejs::Host::npm_install_package(self, package_name, version).await
125 }
126
127 async fn latest_github_release(
128 &mut self,
129 repo: String,
130 options: GithubReleaseOptions,
131 ) -> wasmtime::Result<Result<GithubRelease, String>> {
132 latest::zed::extension::github::Host::latest_github_release(self, repo, options).await
133 }
134
135 async fn current_platform(&mut self) -> Result<(Os, Architecture)> {
136 latest::zed::extension::platform::Host::current_platform(self).await
137 }
138
139 async fn set_language_server_installation_status(
140 &mut self,
141 server_name: String,
142 status: LanguageServerInstallationStatus,
143 ) -> wasmtime::Result<()> {
144 latest::ExtensionImports::set_language_server_installation_status(
145 self,
146 server_name,
147 status.into(),
148 )
149 .await
150 }
151
152 async fn download_file(
153 &mut self,
154 url: String,
155 path: String,
156 file_type: DownloadedFileType,
157 ) -> wasmtime::Result<Result<(), String>> {
158 latest::ExtensionImports::download_file(self, url, path, file_type.into()).await
159 }
160
161 async fn make_file_executable(&mut self, path: String) -> wasmtime::Result<Result<(), String>> {
162 latest::ExtensionImports::make_file_executable(self, path).await
163 }
164}