1use super::latest;
2use crate::wasm_host::WasmState;
3use anyhow::Result;
4use async_trait::async_trait;
5use extension::WorktreeDelegate;
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() -> &'static Linker<WasmState> {
26 static LINKER: OnceLock<Linker<WasmState>> = OnceLock::new();
27 LINKER.get_or_init(|| super::new_linker(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
70#[async_trait]
71impl HostWorktree for WasmState {
72 async fn read_text_file(
73 &mut self,
74 delegate: Resource<Arc<dyn WorktreeDelegate>>,
75 path: String,
76 ) -> wasmtime::Result<Result<String, String>> {
77 latest::HostWorktree::read_text_file(self, delegate, path).await
78 }
79
80 async fn shell_env(
81 &mut self,
82 delegate: Resource<Arc<dyn WorktreeDelegate>>,
83 ) -> wasmtime::Result<EnvVars> {
84 latest::HostWorktree::shell_env(self, delegate).await
85 }
86
87 async fn which(
88 &mut self,
89 delegate: Resource<Arc<dyn WorktreeDelegate>>,
90 binary_name: String,
91 ) -> wasmtime::Result<Option<String>> {
92 latest::HostWorktree::which(self, delegate, binary_name).await
93 }
94
95 fn drop(&mut self, _worktree: Resource<Worktree>) -> Result<()> {
96 // We only ever hand out borrows of worktrees.
97 Ok(())
98 }
99}
100
101#[async_trait]
102impl ExtensionImports for WasmState {
103 async fn node_binary_path(&mut self) -> wasmtime::Result<Result<String, String>> {
104 latest::nodejs::Host::node_binary_path(self).await
105 }
106
107 async fn npm_package_latest_version(
108 &mut self,
109 package_name: String,
110 ) -> wasmtime::Result<Result<String, String>> {
111 latest::nodejs::Host::npm_package_latest_version(self, package_name).await
112 }
113
114 async fn npm_package_installed_version(
115 &mut self,
116 package_name: String,
117 ) -> wasmtime::Result<Result<Option<String>, String>> {
118 latest::nodejs::Host::npm_package_installed_version(self, package_name).await
119 }
120
121 async fn npm_install_package(
122 &mut self,
123 package_name: String,
124 version: String,
125 ) -> wasmtime::Result<Result<(), String>> {
126 latest::nodejs::Host::npm_install_package(self, package_name, version).await
127 }
128
129 async fn latest_github_release(
130 &mut self,
131 repo: String,
132 options: GithubReleaseOptions,
133 ) -> wasmtime::Result<Result<GithubRelease, String>> {
134 latest::zed::extension::github::Host::latest_github_release(self, repo, options).await
135 }
136
137 async fn current_platform(&mut self) -> Result<(Os, Architecture)> {
138 latest::zed::extension::platform::Host::current_platform(self).await
139 }
140
141 async fn set_language_server_installation_status(
142 &mut self,
143 server_name: String,
144 status: LanguageServerInstallationStatus,
145 ) -> wasmtime::Result<()> {
146 latest::ExtensionImports::set_language_server_installation_status(
147 self,
148 server_name,
149 status.into(),
150 )
151 .await
152 }
153
154 async fn download_file(
155 &mut self,
156 url: String,
157 path: String,
158 file_type: DownloadedFileType,
159 ) -> wasmtime::Result<Result<(), String>> {
160 latest::ExtensionImports::download_file(self, url, path, file_type.into()).await
161 }
162
163 async fn make_file_executable(&mut self, path: String) -> wasmtime::Result<Result<(), String>> {
164 latest::ExtensionImports::make_file_executable(self, path).await
165 }
166}