summaryrefslogtreecommitdiff
path: root/cli/lsp/search.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/lsp/search.rs')
-rw-r--r--cli/lsp/search.rs79
1 files changed, 79 insertions, 0 deletions
diff --git a/cli/lsp/search.rs b/cli/lsp/search.rs
new file mode 100644
index 000000000..8933eeb18
--- /dev/null
+++ b/cli/lsp/search.rs
@@ -0,0 +1,79 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+
+use deno_core::error::AnyError;
+use deno_semver::package::PackageNv;
+use deno_semver::Version;
+use std::sync::Arc;
+
+#[async_trait::async_trait]
+pub trait PackageSearchApi {
+ async fn search(&self, query: &str) -> Result<Arc<Vec<String>>, AnyError>;
+ async fn versions(&self, name: &str) -> Result<Arc<Vec<Version>>, AnyError>;
+ async fn exports(&self, nv: &PackageNv)
+ -> Result<Arc<Vec<String>>, AnyError>;
+}
+
+#[cfg(test)]
+pub mod tests {
+ use super::*;
+ use deno_core::anyhow::anyhow;
+ use std::collections::BTreeMap;
+
+ #[derive(Debug, Default)]
+ pub struct TestPackageSearchApi {
+ /// [(name -> [(version -> [export])])]
+ package_versions: BTreeMap<String, BTreeMap<Version, Vec<String>>>,
+ }
+
+ impl TestPackageSearchApi {
+ pub fn with_package_version(
+ mut self,
+ name: &str,
+ version: &str,
+ exports: &[&str],
+ ) -> Self {
+ let exports_by_version =
+ self.package_versions.entry(name.to_string()).or_default();
+ exports_by_version.insert(
+ Version::parse_standard(version).unwrap(),
+ exports.iter().map(|s| s.to_string()).collect(),
+ );
+ self
+ }
+ }
+
+ #[async_trait::async_trait]
+ impl PackageSearchApi for TestPackageSearchApi {
+ async fn search(&self, query: &str) -> Result<Arc<Vec<String>>, AnyError> {
+ let names = self
+ .package_versions
+ .keys()
+ .filter_map(|n| n.contains(query).then(|| n.clone()))
+ .collect::<Vec<_>>();
+ Ok(Arc::new(names))
+ }
+
+ async fn versions(
+ &self,
+ name: &str,
+ ) -> Result<Arc<Vec<Version>>, AnyError> {
+ let Some(exports_by_version) = self.package_versions.get(name) else {
+ return Err(anyhow!("Package not found."));
+ };
+ Ok(Arc::new(exports_by_version.keys().rev().cloned().collect()))
+ }
+
+ async fn exports(
+ &self,
+ nv: &PackageNv,
+ ) -> Result<Arc<Vec<String>>, AnyError> {
+ let Some(exports_by_version) = self.package_versions.get(&nv.name) else {
+ return Err(anyhow!("Package not found."));
+ };
+ let Some(exports) = exports_by_version.get(&nv.version) else {
+ return Err(anyhow!("Package version not found."));
+ };
+ Ok(Arc::new(exports.clone()))
+ }
+ }
+}