pub trait EcosystemHandler:
Send
+ Sync
+ Sized {
type Registry: PackageRegistry + Clone;
type Dependency: DependencyInfo;
type UnifiedDep;
// Required methods
fn new(cache: Arc<HttpCache>) -> Self;
fn registry(&self) -> &Self::Registry;
fn extract_dependency(dep: &Self::UnifiedDep) -> Option<&Self::Dependency>;
fn package_url(name: &str) -> String;
fn ecosystem_display_name() -> &'static str;
fn is_version_latest(version_req: &str, latest: &str) -> bool;
fn format_version_for_edit(dep: &Self::Dependency, version: &str) -> String;
fn is_deprecated(
version: &<Self::Registry as PackageRegistry>::Version,
) -> bool;
fn is_valid_version_syntax(version_req: &str) -> bool;
fn parse_version_req(
version_req: &str,
) -> Option<<Self::Registry as PackageRegistry>::VersionReq>;
// Provided method
fn lockfile_provider(&self) -> Option<Arc<dyn LockFileProvider>> { ... }
}Expand description
Generic handler for LSP operations across ecosystems.
This trait uses Generic Associated Types (GATs) to provide a unified interface for handlers while maintaining strong typing.
Implementors provide ecosystem-specific behavior (registry access, URL construction, version matching) while the generic handler functions provide the common LSP logic.
§Examples
use deps_core::{EcosystemHandler, HttpCache, PackageRegistry, DependencyInfo};
use async_trait::async_trait;
use std::sync::Arc;
struct MyHandler {
registry: MyRegistry,
}
#[async_trait]
impl EcosystemHandler for MyHandler {
type Registry = MyRegistry;
type Dependency = MyDependency;
type UnifiedDep = MyDependency; // In real implementation, this would be UnifiedDependency enum
fn new(_cache: Arc<HttpCache>) -> Self {
Self {
registry: MyRegistry,
}
}
fn registry(&self) -> &Self::Registry {
&self.registry
}
fn extract_dependency(dep: &Self::UnifiedDep) -> Option<&Self::Dependency> {
// In real implementation, match on the enum variant
Some(dep)
}
fn package_url(name: &str) -> String {
format!("https://myregistry.org/package/{}", name)
}
fn ecosystem_display_name() -> &'static str {
"MyRegistry"
}
fn is_version_latest(version_req: &str, latest: &str) -> bool {
version_req == latest
}
fn format_version_for_edit(_dep: &Self::Dependency, version: &str) -> String {
format!("\"{}\"", version)
}
fn is_deprecated(version: &MyVersion) -> bool {
version.yanked
}
fn is_valid_version_syntax(_version_req: &str) -> bool {
true
}
fn parse_version_req(version_req: &str) -> Option<String> {
Some(version_req.to_string())
}
}Required Associated Types§
Sourcetype Registry: PackageRegistry + Clone
type Registry: PackageRegistry + Clone
Registry type for this ecosystem.
Sourcetype Dependency: DependencyInfo
type Dependency: DependencyInfo
Dependency type for this ecosystem.
Sourcetype UnifiedDep
type UnifiedDep
Unified dependency type (typically deps_lsp::document::UnifiedDependency).
This is an associated type to avoid unsafe transmute when extracting ecosystem-specific dependencies from the unified enum.
Required Methods§
Sourcefn extract_dependency(dep: &Self::UnifiedDep) -> Option<&Self::Dependency>
fn extract_dependency(dep: &Self::UnifiedDep) -> Option<&Self::Dependency>
Extract typed dependency from a unified dependency enum.
Returns Some if the unified dependency matches this handler’s ecosystem, None otherwise.
Sourcefn package_url(name: &str) -> String
fn package_url(name: &str) -> String
Package URL for this ecosystem (e.g., crates.io, npmjs.com).
Used in inlay hint commands and hover tooltips.
Sourcefn ecosystem_display_name() -> &'static str
fn ecosystem_display_name() -> &'static str
Display name for the ecosystem (e.g., “crates.io”, “PyPI”).
Used in LSP command titles.
Sourcefn is_version_latest(version_req: &str, latest: &str) -> bool
fn is_version_latest(version_req: &str, latest: &str) -> bool
Check if version is latest (ecosystem-specific logic).
Returns true if the latest version satisfies the version requirement, meaning the dependency is up-to-date within its constraint.
Sourcefn format_version_for_edit(dep: &Self::Dependency, version: &str) -> String
fn format_version_for_edit(dep: &Self::Dependency, version: &str) -> String
Format a version string for editing in the manifest.
Different ecosystems have different formatting conventions:
- Cargo:
"1.0.0"(bare semver) - npm:
"1.0.0"(bare version, caret added by package manager) - PyPI PEP 621:
>=1.0.0(no quotes in array) - PyPI Poetry:
"^1.0.0"(caret in quotes)
Sourcefn is_deprecated(version: &<Self::Registry as PackageRegistry>::Version) -> bool
fn is_deprecated(version: &<Self::Registry as PackageRegistry>::Version) -> bool
Check if a version is deprecated/yanked.
Returns true if the version should be filtered out from suggestions.
Sourcefn is_valid_version_syntax(version_req: &str) -> bool
fn is_valid_version_syntax(version_req: &str) -> bool
Validate version requirement syntax.
Returns true if the version requirement is valid for this ecosystem. Used for diagnostic validation (semver for Cargo, PEP 440 for PyPI, etc.)
Sourcefn parse_version_req(
version_req: &str,
) -> Option<<Self::Registry as PackageRegistry>::VersionReq>
fn parse_version_req( version_req: &str, ) -> Option<<Self::Registry as PackageRegistry>::VersionReq>
Parse a version requirement string into the registry’s VersionReq type.
Returns None if the version requirement is invalid.
Provided Methods§
Sourcefn lockfile_provider(&self) -> Option<Arc<dyn LockFileProvider>>
fn lockfile_provider(&self) -> Option<Arc<dyn LockFileProvider>>
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.