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