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