pub struct PackageVersions {
pub latest: ConcreteVersion,
pub available: Arc<[ConcreteVersion]>,
pub yanked: Arc<[(ConcreteVersion, RemovalStatus)]>,
pub published_at: Option<PublishTime>,
}Expand description
Registry version data for one package, fetched together in a single round trip.
latest and available are deliberately asymmetric — this is load-bearing, not an
oversight:
latestcomes from this ecosystem’s ownRegistry::select_latest_matching(.., "*")pick, which excludes yanked (and, for semver/node-semver*, prerelease) versions — the same valueget_latest_matchingreturned before this type existed.availableis the unfilteredget_versionsoutput: every published version, newest-first, yanked and prerelease entries included.
The unsatisfiable-requirement check (see crate::lsp_helpers::requirement_is_unsatisfiable)
scans available and deliberately does not filter it: a requirement that only matches a
yanked or prerelease version is still satisfied, so filtering available the same way
latest is filtered would produce false “no published version satisfies” warnings.
yanked is the subset of available (same version-string encoding) that the registry
reported as yanked/deprecated, paired with each entry’s RemovalStatus. It exists
because Registry::get_latest_matching — the call that used to populate this cache —
filters yanked entries out by contract on every current registry implementation, so a
per-version yanked flag threaded through that call would always read false (see
#233). available now comes from the unfiltered get_versions instead, which does
observe yanked entries, so yanked is derived from that same fetch rather than
discarded.
The status rides alongside each version (rather than a bare membership list) so
crate::lsp_helpers::generate_diagnostics_from_cache’s #247 “requirement satisfiable
only by a yanked version” check can gate its own package-level-deprecation suppression
on AdvisoryDeprecated specifically, never on a genuine Yanked finding — mirroring
VersionData::outcomes’s D5 gate for the #263 in-use-version check (see #437).
Fields§
§latest: ConcreteVersionLatest usable version for this package.
available: Arc<[ConcreteVersion]>Every published version, newest-first, unfiltered.
yanked: Arc<[(ConcreteVersion, RemovalStatus)]>Subset of available reported as yanked/deprecated by the registry, each paired
with its RemovalStatus.
published_at: Option<PublishTime>When latest was published, if the registry exposes it. None when
the ecosystem doesn’t wire crate::Version::published_at or the fetch
never ran.
Deliberately a field on this single per-package struct rather than a
second parallel map keyed alongside latest — the earlier two-map
design (issue #227 critique C3) let latest and its age drift apart
silently whenever one map was updated (e.g. lockfile-resolved
overwrite) without the other. Bundling them here makes that
desync impossible: whoever sets latest sets published_at too.
Implementations§
Source§impl PackageVersions
impl PackageVersions
Sourcepub fn latest_only(latest: impl Into<ConcreteVersion>) -> Self
pub fn latest_only(latest: impl Into<ConcreteVersion>) -> Self
Builds a PackageVersions from only the “latest” version string, with available
populated as the single-element list [latest].
Test-only in intent. The one-element available this produces is a real, if
small, version list — it is not “empty/unknown”, so requirement_is_unsatisfiable
will evaluate a requirement against it. Do not use this for a lock-file-only
population path that has no real version list to offer (use
latest_without_list there instead, which leaves
available genuinely empty) — that exact substitution is the false-positive N5 was
written to prevent: it would let the unsatisfiable-requirement check produce a
verdict against a fabricated one-entry list before any registry fetch has run. Real
registry fetches always populate available from the full get_versions result
instead of using either constructor.
§Examples
use deps_core::{ConcreteVersion, PackageVersions};
let versions = PackageVersions::latest_only("1.0.214");
assert_eq!(versions.latest, "1.0.214");
assert_eq!(&*versions.available, &[ConcreteVersion::new("1.0.214")]);Sourcepub fn latest_without_list(latest: impl Into<ConcreteVersion>) -> Self
pub fn latest_without_list(latest: impl Into<ConcreteVersion>) -> Self
Builds a PackageVersions with no version list — used where only the “latest” value
is known and probing further would be misleading, notably the lock-file population
path (crates/deps-lsp/src/document/lifecycle.rs), which must not populate a
plausible-looking one-element available list before any registry fetch has run: the
unsatisfiable-requirement check treats an empty available as “still loading, skip”.
§Examples
use deps_core::PackageVersions;
let versions = PackageVersions::latest_without_list("1.0.195");
assert_eq!(versions.latest, "1.0.195");
assert!(versions.available.is_empty());Trait Implementations§
Source§impl Clone for PackageVersions
impl Clone for PackageVersions
Source§fn clone(&self) -> PackageVersions
fn clone(&self) -> PackageVersions
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for PackageVersions
impl Debug for PackageVersions
impl Eq for PackageVersions
Source§impl PartialEq for PackageVersions
impl PartialEq for PackageVersions
Source§fn eq(&self, other: &PackageVersions) -> bool
fn eq(&self, other: &PackageVersions) -> bool
self and other values to be equal, and is used by ==.impl StructuralPartialEq for PackageVersions
Auto Trait Implementations§
impl Freeze for PackageVersions
impl RefUnwindSafe for PackageVersions
impl Send for PackageVersions
impl Sync for PackageVersions
impl Unpin for PackageVersions
impl UnsafeUnpin for PackageVersions
impl UnwindSafe for PackageVersions
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.