since_v0_0_1.rs

  1use super::latest;
  2use crate::wasm_host::WasmState;
  3use anyhow::Result;
  4use async_trait::async_trait;
  5use language::{LanguageServerBinaryStatus, LspAdapterDelegate};
  6use semantic_version::SemanticVersion;
  7use std::sync::{Arc, OnceLock};
  8use wasmtime::component::{Linker, Resource};
  9
 10pub const MIN_VERSION: SemanticVersion = SemanticVersion::new(0, 0, 1);
 11
 12wasmtime::component::bindgen!({
 13    async: true,
 14    path: "../extension_api/wit/since_v0.0.1",
 15    with: {
 16         "worktree": ExtensionWorktree,
 17    },
 18});
 19
 20pub type ExtensionWorktree = Arc<dyn LspAdapterDelegate>;
 21
 22pub fn linker() -> &'static Linker<WasmState> {
 23    static LINKER: OnceLock<Linker<WasmState>> = OnceLock::new();
 24    LINKER.get_or_init(|| super::new_linker(Extension::add_to_linker))
 25}
 26
 27impl From<latest::Os> for Os {
 28    fn from(value: latest::Os) -> Self {
 29        match value {
 30            latest::Os::Mac => Os::Mac,
 31            latest::Os::Linux => Os::Linux,
 32            latest::Os::Windows => Os::Windows,
 33        }
 34    }
 35}
 36
 37impl From<latest::Architecture> for Architecture {
 38    fn from(value: latest::Architecture) -> Self {
 39        match value {
 40            latest::Architecture::Aarch64 => Self::Aarch64,
 41            latest::Architecture::X86 => Self::X86,
 42            latest::Architecture::X8664 => Self::X8664,
 43        }
 44    }
 45}
 46
 47impl From<latest::GithubRelease> for GithubRelease {
 48    fn from(value: latest::GithubRelease) -> Self {
 49        Self {
 50            version: value.version,
 51            assets: value.assets.into_iter().map(|asset| asset.into()).collect(),
 52        }
 53    }
 54}
 55
 56impl From<latest::GithubReleaseAsset> for GithubReleaseAsset {
 57    fn from(value: latest::GithubReleaseAsset) -> Self {
 58        Self {
 59            name: value.name,
 60            download_url: value.download_url,
 61        }
 62    }
 63}
 64
 65impl From<GithubReleaseOptions> for latest::GithubReleaseOptions {
 66    fn from(value: GithubReleaseOptions) -> Self {
 67        Self {
 68            require_assets: value.require_assets,
 69            pre_release: value.pre_release,
 70        }
 71    }
 72}
 73
 74impl From<DownloadedFileType> for latest::DownloadedFileType {
 75    fn from(value: DownloadedFileType) -> Self {
 76        match value {
 77            DownloadedFileType::Gzip => latest::DownloadedFileType::Gzip,
 78            DownloadedFileType::GzipTar => latest::DownloadedFileType::GzipTar,
 79            DownloadedFileType::Zip => latest::DownloadedFileType::Zip,
 80            DownloadedFileType::Uncompressed => latest::DownloadedFileType::Uncompressed,
 81        }
 82    }
 83}
 84
 85impl From<latest::LanguageServerConfig> for LanguageServerConfig {
 86    fn from(value: latest::LanguageServerConfig) -> Self {
 87        Self {
 88            name: value.name,
 89            language_name: value.language_name,
 90        }
 91    }
 92}
 93
 94impl From<Command> for latest::Command {
 95    fn from(value: Command) -> Self {
 96        Self {
 97            command: value.command,
 98            args: value.args,
 99            env: value.env,
100        }
101    }
102}
103
104#[async_trait]
105impl HostWorktree for WasmState {
106    async fn read_text_file(
107        &mut self,
108        delegate: Resource<Arc<dyn LspAdapterDelegate>>,
109        path: String,
110    ) -> wasmtime::Result<Result<String, String>> {
111        latest::HostWorktree::read_text_file(self, delegate, path).await
112    }
113
114    async fn shell_env(
115        &mut self,
116        delegate: Resource<Arc<dyn LspAdapterDelegate>>,
117    ) -> wasmtime::Result<EnvVars> {
118        latest::HostWorktree::shell_env(self, delegate).await
119    }
120
121    async fn which(
122        &mut self,
123        delegate: Resource<Arc<dyn LspAdapterDelegate>>,
124        binary_name: String,
125    ) -> wasmtime::Result<Option<String>> {
126        latest::HostWorktree::which(self, delegate, binary_name).await
127    }
128
129    fn drop(&mut self, _worktree: Resource<Worktree>) -> Result<()> {
130        Ok(())
131    }
132}
133
134#[async_trait]
135impl ExtensionImports for WasmState {
136    async fn node_binary_path(&mut self) -> wasmtime::Result<Result<String, String>> {
137        latest::ExtensionImports::node_binary_path(self).await
138    }
139
140    async fn npm_package_latest_version(
141        &mut self,
142        package_name: String,
143    ) -> wasmtime::Result<Result<String, String>> {
144        latest::ExtensionImports::npm_package_latest_version(self, package_name).await
145    }
146
147    async fn npm_package_installed_version(
148        &mut self,
149        package_name: String,
150    ) -> wasmtime::Result<Result<Option<String>, String>> {
151        latest::ExtensionImports::npm_package_installed_version(self, package_name).await
152    }
153
154    async fn npm_install_package(
155        &mut self,
156        package_name: String,
157        version: String,
158    ) -> wasmtime::Result<Result<(), String>> {
159        latest::ExtensionImports::npm_install_package(self, package_name, version).await
160    }
161
162    async fn latest_github_release(
163        &mut self,
164        repo: String,
165        options: GithubReleaseOptions,
166    ) -> wasmtime::Result<Result<GithubRelease, String>> {
167        Ok(
168            latest::ExtensionImports::latest_github_release(self, repo, options.into())
169                .await?
170                .map(|github| github.into()),
171        )
172    }
173
174    async fn current_platform(&mut self) -> Result<(Os, Architecture)> {
175        latest::ExtensionImports::current_platform(self)
176            .await
177            .map(|(os, arch)| (os.into(), arch.into()))
178    }
179
180    async fn set_language_server_installation_status(
181        &mut self,
182        server_name: String,
183        status: LanguageServerInstallationStatus,
184    ) -> wasmtime::Result<()> {
185        let status = match status {
186            LanguageServerInstallationStatus::CheckingForUpdate => {
187                LanguageServerBinaryStatus::CheckingForUpdate
188            }
189            LanguageServerInstallationStatus::Downloading => {
190                LanguageServerBinaryStatus::Downloading
191            }
192            LanguageServerInstallationStatus::Cached
193            | LanguageServerInstallationStatus::Downloaded => LanguageServerBinaryStatus::None,
194            LanguageServerInstallationStatus::Failed(error) => {
195                LanguageServerBinaryStatus::Failed { error }
196            }
197        };
198
199        self.host
200            .language_registry
201            .update_lsp_status(language::LanguageServerName(server_name.into()), status);
202        Ok(())
203    }
204
205    async fn download_file(
206        &mut self,
207        url: String,
208        path: String,
209        file_type: DownloadedFileType,
210    ) -> wasmtime::Result<Result<(), String>> {
211        latest::ExtensionImports::download_file(self, url, path, file_type.into()).await
212    }
213}