Skip to main content

requirement_is_unsatisfiable

Function requirement_is_unsatisfiable 

Source
pub fn requirement_is_unsatisfiable(
    formatter: &dyn EcosystemFormatter,
    requirement: &VersionReq,
    available: &[ConcreteVersion],
) -> bool
Expand description

Returns true when no published version satisfies requirement.

available must be non-empty, requirement must be a concrete (non-empty, resolved, not implausibly long) constraint, and no entry in available — of any kind: stable, prerelease, or yanked — may satisfy it. All of the following must hold for true:

  1. !available.is_empty() — an empty or not-yet-loaded list means “unknown”, not “unsatisfiable” (FR-004: no diagnostic while loading or offline).
  2. !requirement.as_str().trim().is_empty().
  3. requirement.as_str().len() <= MAX_REQUIREMENT_LEN — see that constant’s docs; an oversized requirement is treated the same as “unmodellable” (suppressed, not warned).
  4. !formatter.requirement_is_unresolved(requirement) (FR-005) — an unresolved placeholder requirement was never actually checked against anything.
  5. !formatter.requirement_is_undecidable_given_available(requirement, available) — this ecosystem’s registry can hide a published version that would have decided the match.
  6. formatter.compile_requirement(requirement) returns Some(matcher) — this ecosystem opted in and the requirement string itself parses.
  7. Scanning available with matcher.matches: at least one candidate returned Some(false), and none returned Some(true). Candidates returning None (unparseable candidate strings) are skipped and count toward neither side — condition 7’s “at least one Some(false)” is load-bearing: if every candidate is unparseable, nothing was decided, so the verdict is false (no diagnostic) rather than a vacuous true.

The scan short-circuits on the first Some(true) — O(N) worst case, and the newest-first ordering of available means a satisfiable requirement typically exits within the first few entries.

§Examples

use deps_core::lsp_helpers::{
    requirement_is_unsatisfiable, DiagnosticMessages, DiagnosticPolicy, OsvNaming,
    PackageNaming, PackageRendering, RequirementMatcher, RequirementResolution, SourcePolicy,
};
use deps_core::{ConcreteVersion, PackageName, VersionReq};

struct ExactMatcher(String);
impl RequirementMatcher for ExactMatcher {
    fn matches(&self, version: &ConcreteVersion) -> Option<bool> {
        Some(version.as_str() == self.0)
    }
}

struct ExactFormatter;
impl PackageNaming for ExactFormatter {}
impl PackageRendering for ExactFormatter {
    fn format_version_for_text_edit(&self, version: &ConcreteVersion) -> String {
        version.to_string()
    }
    fn package_url(&self, name: &PackageName) -> String {
        name.to_string()
    }
}
impl RequirementResolution for ExactFormatter {
    fn compile_requirement(
        &self,
        requirement: &VersionReq,
    ) -> Option<Box<dyn RequirementMatcher>> {
        Some(Box::new(ExactMatcher(requirement.as_str().to_string())))
    }
}
impl DiagnosticMessages for ExactFormatter {}
impl DiagnosticPolicy for ExactFormatter {}
impl SourcePolicy for ExactFormatter {}
impl OsvNaming for ExactFormatter {}

let available = vec![ConcreteVersion::new("1.0.0"), ConcreteVersion::new("0.9.0")];
assert!(requirement_is_unsatisfiable(
    &ExactFormatter,
    &VersionReq::new("2.0.0"),
    &available,
));
assert!(!requirement_is_unsatisfiable(
    &ExactFormatter,
    &VersionReq::new("1.0.0"),
    &available,
));