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§
Sourcefn id(&self) -> &'static str
fn id(&self) -> &'static str
Unique identifier (e.g., “cargo”, “npm”, “pypi”)
This identifier is used for ecosystem registration and routing.
Sourcefn display_name(&self) -> &'static str
fn display_name(&self) -> &'static str
Human-readable name (e.g., “Cargo (Rust)”, “npm (JavaScript)”)
This name is displayed in diagnostic messages and logs.
Sourcefn manifest_filenames(&self) -> &[&'static str]
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.
Sourcefn 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 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,
Sourcefn registry(&self) -> Arc<dyn Registry>
fn registry(&self) -> Arc<dyn Registry>
Get the registry client for this ecosystem
The registry provides version lookup and package search capabilities.
Sourcefn 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_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 manifestcached_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 dataconfig- User configuration for hint display
Sourcefn 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_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 manifestposition- Cursor position in documentcached_versions- Pre-fetched latest version information from registryresolved_versions- Resolved versions from lock file (takes precedence for “Current” display)
Sourcefn 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_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 manifestposition- Cursor position in documentcached_versions- Pre-fetched version informationuri- Document URI for workspace edits
Sourcefn 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_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 manifestcached_versions- Pre-fetched latest version information from registryresolved_versions- Resolved versions from lock fileuri- Document URI for diagnostic reporting
Sourcefn 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 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 manifestposition- Cursor position in documentcontent- Full document content for context analysis
Provided Methods§
Sourcefn lockfile_filenames(&self) -> &[&'static str]
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.
Sourcefn lockfile_provider(&self) -> Option<Arc<dyn LockFileProvider>>
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.