Skip to main content

DiagnosticPolicy

Trait DiagnosticPolicy 

Source
pub trait DiagnosticPolicy: Send + Sync {
    // Provided methods
    fn strict_semver_prerelease_exclusion(&self) -> bool { ... }
    fn supports_package_rename(&self) -> bool { ... }
    fn yanked_diagnostic_applies_to(
        &self,
        _dep: &dyn Dependency,
        _requirement: &VersionReq,
    ) -> bool { ... }
}
Expand description

Per-ecosystem opt-outs for which diagnostics apply to which dependency/requirement shapes.

Implementors guarantee these hooks only ever narrow or disable a diagnostic a shared, ecosystem-agnostic pass would otherwise emit unconditionally — never widen or fabricate one. An override does not always mean “this ecosystem is broken”: NpmFormatter returns false from yanked_diagnostic_applies_to unconditionally not because the underlying signal is wrong, but to avoid duplicating the separate #205 package-level deprecation diagnostic that would otherwise fire alongside it.

Provided Methods§

Source

fn strict_semver_prerelease_exclusion(&self) -> bool

Whether this ecosystem’s requirement/version syntax follows strict SemVer 2.0.0 pre-release semantics: a pre-release version (X.Y.Z-pre) is excluded from matching requirement unless requirement itself pins to the same X.Y.Z tuple with a pre-release tag — the rule Cargo’s semver crate and npm’s node-semver both implement, and that compile_requirement’s matcher inherits from its underlying comparator.

Used by crate::lsp_helpers::requirement_is_unsatisfiable’s caller in generate_diagnostics_from_cache to decide whether the unsatisfiable-requirement WARNING should be enriched with a mention of a published pre-release that would satisfy requirement if pre-release exclusion were relaxed (#299). Maven/NuGet/Composer/Gradle use non-strict, ecosystem-specific range models where this premise does not hold — they must not override this.

Default false. deps-cargo, deps-npm, and deps-swift override this to true.

§Examples
use deps_core::lsp_helpers::DiagnosticPolicy;

struct DefaultFormatter;
impl DiagnosticPolicy for DefaultFormatter {}

assert!(!DefaultFormatter.strict_semver_prerelease_exclusion());
Source

fn supports_package_rename(&self) -> bool

Whether this ecosystem’s deprecation payload (crate::Deprecation::replacement) is safe to offer as a “Replace with X” rename quickfix.

Default false. Only an ecosystem whose replacement name comes from a structured, registry-validated field may override this to true — never one synthesized by parsing free text, which is a typosquatting vector (npm’s deprecated message names a successor only in prose). ComposerFormatter overrides this to true: Packagist’s abandoned replacement is a real package name field, not extracted text.

Source

fn yanked_diagnostic_applies_to( &self, _dep: &dyn Dependency, _requirement: &VersionReq, ) -> bool

Whether the “requirement satisfiable only by a yanked version” diagnostic (crate::lsp_helpers::requirement_matches_only_yanked) should evaluate requirement at all for this ecosystem.

Default true — no restriction, every requirement shape is checked. Override to false for a requirement shape (or, returning false unconditionally, for every requirement) where this diagnostic would duplicate a more specific one, or where this ecosystem’s Version::removal_status() is not a reliable enough per-version signal. This is independent of Registry::reports_yanked: that flag gates whether removal_status() data is trusted at all (and thus whether the separate #263 in-use-version yanked check runs), while this hook only narrows this diagnostic.

dep is passed alongside requirement (rather than requirement alone) so an implementor can key its decision off the dependency’s package name — needed by DenoFormatter (#448) to tell its jsr:- and npm:-scheme specifiers apart, since the scheme lives in the name, not in the requirement text. At the sole call site (crate::lsp_helpers::diagnostics::generate_diagnostics_from_cache), requirement is always dep.version_requirement().unwrap() for the same dep — the two are never independent, though an implementor is free to key off either or both.

DenoFormatter returns false unconditionally for npm: specifiers, mirroring NpmFormatter (#448), and applies unconditionally (true, the same as leaving this hook at its default) for jsr: specifiers, for any requirement shape (#454): unlike npm’s deprecated, JSR’s yanked flag is a genuine per-version signal with no package-level deprecation diagnostic to conflate with, so jsr: needs no restriction here at all — see that formatter’s docs. NpmFormatter returns false unconditionally (#436): npm’s AdvisoryDeprecated is genuinely per-version but commonly applied package-wide, so even an exact pin would often just duplicate the dedicated package-level deprecation diagnostic (DiagnosticMessages::deprecated_message, issue #205); npm keeps reports_yanked() == true; so the #263 in-use-version check stays live. ComposerFormatter does not override this hook at all — it opts out at the registry level instead (Registry::reports_yanked == false, pre-dating #436, independently justified by #233 R2): Packagist’s abandoned is package-level via p2 minified inheritance, so its yanked map is never populated and this hook has nothing to restrict.

§Examples
use deps_core::lsp_helpers::DiagnosticPolicy;
use deps_core::{Dependency, PackageName, VersionReq};

struct DefaultFormatter;
impl DiagnosticPolicy for DefaultFormatter {}

let dep = FakeDep(PackageName::new("example"));
assert!(DefaultFormatter.yanked_diagnostic_applies_to(&dep, &VersionReq::new("^1.2")));

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§