Ecosystem

Trait Ecosystem 

Source
pub trait Ecosystem: Send + Sync {
Show 13 methods // Required methods fn id(&self) -> &'static str; fn display_name(&self) -> &'static str; fn manifest_filenames(&self) -> &[&'static str]; fn parse_manifest<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, content: &'life1 str, uri: &'life2 Uri, ) -> Pin<Box<dyn Future<Output = Result<Box<dyn ParseResult>>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn registry(&self) -> Arc<dyn Registry>; fn generate_inlay_hints<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>( &'life0 self, parse_result: &'life1 dyn ParseResult, cached_versions: &'life2 HashMap<String, String>, resolved_versions: &'life3 HashMap<String, String>, loading_state: LoadingState, config: &'life4 EcosystemConfig, ) -> Pin<Box<dyn Future<Output = Vec<InlayHint>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait; fn generate_hover<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, parse_result: &'life1 dyn ParseResult, position: Position, cached_versions: &'life2 HashMap<String, String>, resolved_versions: &'life3 HashMap<String, String>, ) -> Pin<Box<dyn Future<Output = Option<Hover>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait; fn generate_code_actions<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, parse_result: &'life1 dyn ParseResult, position: Position, cached_versions: &'life2 HashMap<String, String>, uri: &'life3 Uri, ) -> Pin<Box<dyn Future<Output = Vec<CodeAction>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait; fn generate_diagnostics<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>( &'life0 self, parse_result: &'life1 dyn ParseResult, cached_versions: &'life2 HashMap<String, String>, resolved_versions: &'life3 HashMap<String, String>, uri: &'life4 Uri, ) -> Pin<Box<dyn Future<Output = Vec<Diagnostic>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait; fn generate_completions<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, parse_result: &'life1 dyn ParseResult, position: Position, content: &'life2 str, ) -> Pin<Box<dyn Future<Output = Vec<CompletionItem>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn as_any(&self) -> &dyn Any; // Provided methods fn lockfile_filenames(&self) -> &[&'static str] { ... } fn lockfile_provider(&self) -> Option<Arc<dyn LockFileProvider>> { ... }
}
Expand description

Main trait that all ecosystem implementations must implement.

Each ecosystem (Cargo, npm, PyPI, etc.) provides its own implementation. This trait defines the contract for parsing manifests, fetching registry data, and generating LSP responses.

§Type Erasure

This trait uses Box<dyn Trait> instead of associated types to allow runtime polymorphism and dynamic ecosystem registration.

§Examples

use deps_core::{Ecosystem, ParseResult, Registry, EcosystemConfig};
use async_trait::async_trait;
use std::sync::Arc;
use std::any::Any;
use tower_lsp_server::ls_types::{Uri, InlayHint, Hover, CodeAction, Diagnostic, CompletionItem, Position};

struct MyEcosystem {
    registry: Arc<dyn Registry>,
}

#[async_trait]
impl Ecosystem for MyEcosystem {
    fn id(&self) -> &'static str {
        "my-ecosystem"
    }

    fn display_name(&self) -> &'static str {
        "My Ecosystem"
    }

    fn manifest_filenames(&self) -> &[&'static str] {
        &["my-manifest.toml"]
    }

    async fn parse_manifest(
        &self,
        content: &str,
        uri: &Uri,
    ) -> deps_core::error::Result<Box<dyn ParseResult>> {
        // Implementation here
        todo!()
    }

    fn registry(&self) -> Arc<dyn Registry> {
        self.registry.clone()
    }

    async fn generate_inlay_hints(
        &self,
        parse_result: &dyn ParseResult,
        cached_versions: &std::collections::HashMap<String, String>,
        resolved_versions: &std::collections::HashMap<String, String>,
        loading_state: deps_core::LoadingState,
        config: &EcosystemConfig,
    ) -> Vec<InlayHint> {
        let _ = (resolved_versions, loading_state); // Use resolved versions for lock file support
        vec![]
    }

    async fn generate_hover(
        &self,
        parse_result: &dyn ParseResult,
        position: Position,
        cached_versions: &std::collections::HashMap<String, String>,
        resolved_versions: &std::collections::HashMap<String, String>,
    ) -> Option<Hover> {
        let _ = resolved_versions; // Use resolved versions for lock file support
        None
    }

    async fn generate_code_actions(
        &self,
        parse_result: &dyn ParseResult,
        position: Position,
        cached_versions: &std::collections::HashMap<String, String>,
        uri: &Uri,
    ) -> Vec<CodeAction> {
        vec![]
    }

    async fn generate_diagnostics(
        &self,
        parse_result: &dyn ParseResult,
        cached_versions: &std::collections::HashMap<String, String>,
        resolved_versions: &std::collections::HashMap<String, String>,
        uri: &Uri,
    ) -> Vec<Diagnostic> {
        let _ = resolved_versions; // Use resolved versions for lock file support
        vec![]
    }

    async fn generate_completions(
        &self,
        parse_result: &dyn ParseResult,
        position: Position,
        content: &str,
    ) -> Vec<CompletionItem> {
        vec![]
    }

    fn as_any(&self) -> &dyn Any {
        self
    }
}

Required Methods§

Source

fn id(&self) -> &'static str

Unique identifier (e.g., “cargo”, “npm”, “pypi”)

This identifier is used for ecosystem registration and routing.

Source

fn display_name(&self) -> &'static str

Human-readable name (e.g., “Cargo (Rust)”, “npm (JavaScript)”)

This name is displayed in diagnostic messages and logs.

Source

fn manifest_filenames(&self) -> &[&'static str]

Manifest filenames this ecosystem handles (e.g., [“Cargo.toml”])

The ecosystem registry uses these filenames to route file URIs to the appropriate ecosystem implementation.

Source

fn parse_manifest<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, content: &'life1 str, uri: &'life2 Uri, ) -> Pin<Box<dyn Future<Output = Result<Box<dyn ParseResult>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Parse a manifest file and return parsed result

§Arguments
  • content - Raw file content
  • uri - Document URI for position tracking
§Errors

Returns error if manifest cannot be parsed

Source

fn registry(&self) -> Arc<dyn Registry>

Get the registry client for this ecosystem

The registry provides version lookup and package search capabilities.

Source

fn generate_inlay_hints<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>( &'life0 self, parse_result: &'life1 dyn ParseResult, cached_versions: &'life2 HashMap<String, String>, resolved_versions: &'life3 HashMap<String, String>, loading_state: LoadingState, config: &'life4 EcosystemConfig, ) -> Pin<Box<dyn Future<Output = Vec<InlayHint>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait,

Generate inlay hints for the document

Inlay hints show additional version information inline in the editor.

§Arguments
  • parse_result - Parsed dependencies from manifest
  • cached_versions - Pre-fetched version information (name -> latest version from registry)
  • resolved_versions - Resolved versions from lock file (name -> locked version)
  • loading_state - Current loading state for registry data
  • config - User configuration for hint display
Source

fn generate_hover<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, parse_result: &'life1 dyn ParseResult, position: Position, cached_versions: &'life2 HashMap<String, String>, resolved_versions: &'life3 HashMap<String, String>, ) -> Pin<Box<dyn Future<Output = Option<Hover>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Generate hover information for a position

Shows package information when hovering over a dependency name or version.

§Arguments
  • parse_result - Parsed dependencies from manifest
  • position - Cursor position in document
  • cached_versions - Pre-fetched latest version information from registry
  • resolved_versions - Resolved versions from lock file (takes precedence for “Current” display)
Source

fn generate_code_actions<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, parse_result: &'life1 dyn ParseResult, position: Position, cached_versions: &'life2 HashMap<String, String>, uri: &'life3 Uri, ) -> Pin<Box<dyn Future<Output = Vec<CodeAction>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Generate code actions for a position

Code actions provide quick fixes like “Update to latest version”.

§Arguments
  • parse_result - Parsed dependencies from manifest
  • position - Cursor position in document
  • cached_versions - Pre-fetched version information
  • uri - Document URI for workspace edits
Source

fn generate_diagnostics<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>( &'life0 self, parse_result: &'life1 dyn ParseResult, cached_versions: &'life2 HashMap<String, String>, resolved_versions: &'life3 HashMap<String, String>, uri: &'life4 Uri, ) -> Pin<Box<dyn Future<Output = Vec<Diagnostic>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait,

Generate diagnostics for the document

Diagnostics highlight issues like outdated dependencies or unknown packages.

§Arguments
  • parse_result - Parsed dependencies from manifest
  • cached_versions - Pre-fetched latest version information from registry
  • resolved_versions - Resolved versions from lock file
  • uri - Document URI for diagnostic reporting
Source

fn generate_completions<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, parse_result: &'life1 dyn ParseResult, position: Position, content: &'life2 str, ) -> Pin<Box<dyn Future<Output = Vec<CompletionItem>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Generate completions for a position

Provides autocomplete suggestions for package names and versions.

§Arguments
  • parse_result - Parsed dependencies from manifest
  • position - Cursor position in document
  • content - Full document content for context analysis
Source

fn as_any(&self) -> &dyn Any

Support for downcasting to concrete ecosystem type

This allows ecosystem-specific operations when needed.

Provided Methods§

Source

fn lockfile_filenames(&self) -> &[&'static str]

Lock file filenames this ecosystem uses (e.g., [“Cargo.lock”])

Used for file watching - LSP will monitor changes to these files and refresh UI when they change. Returns empty slice if ecosystem doesn’t use lock files.

§Default Implementation

Returns empty slice by default, indicating no lock files are used.

Source

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

Get the lock file provider for this ecosystem.

Returns None if the ecosystem doesn’t support lock files. Lock files provide resolved dependency versions without network requests.

Implementors§