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§
Sourcefn strict_semver_prerelease_exclusion(&self) -> bool
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());Sourcefn supports_package_rename(&self) -> bool
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.
Sourcefn yanked_diagnostic_applies_to(
&self,
_dep: &dyn Dependency,
_requirement: &VersionReq,
) -> bool
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".