EcosystemHandler

Trait EcosystemHandler 

Source
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§

Source

type Registry: PackageRegistry + Clone

Registry type for this ecosystem.

Source

type Dependency: DependencyInfo

Dependency type for this ecosystem.

Source

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§

Source

fn new(cache: Arc<HttpCache>) -> Self

Create a new handler with the given cache.

Source

fn registry(&self) -> &Self::Registry

Get the registry instance.

Source

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.

Source

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.

Source

fn ecosystem_display_name() -> &'static str

Display name for the ecosystem (e.g., “crates.io”, “PyPI”).

Used in LSP command titles.

Source

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.

Source

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)
Source

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.

Source

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.)

Source

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§

Source

fn lockfile_provider(&self) -> Option<Arc<dyn LockFileProvider>>

Get lock file provider for this ecosystem.

Returns None if the ecosystem doesn’t support lock files. Default implementation returns None.

§Examples
// Override in handler implementation:
fn lockfile_provider(&self) -> Option<Arc<dyn LockFileProvider>> {
    Some(Arc::new(MyLockParser))
}

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.

Implementors§