#[non_exhaustive]pub struct FetchResult {
pub versions: HashMap<PackageName, PackageVersions>,
pub yanked_versions: HashMap<PackageName, (ConcreteVersion, RemovalStatus)>,
pub deprecations: HashMap<PackageName, Deprecation>,
pub fetch_failed: HashMap<PackageName, FetchFailure>,
pub no_comparable_versions: HashSet<PackageName>,
pub failure_summary: Option<FailureSummary>,
pub licenses: HashMap<PackageName, Vec<String>>,
}Expand description
Result of parallel version fetching.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.versions: HashMap<PackageName, PackageVersions>Successfully fetched versions (package -> latest + full version list)
yanked_versions: HashMap<PackageName, (ConcreteVersion, RemovalStatus)>Yanked-version findings, keyed by raw package name (unlike
DocumentState::signals.outcomes, which is normalized-keyed — see
§3.1 of the design), to (the version string found yanked, its
RemovalStatus). The status rides alongside so #205’s package-level
deprecation diagnostic can gate its yanked-check suppression on
AdvisoryDeprecated specifically, never a genuine Yanked finding.
Callers must re-key through EcosystemFormatter::normalize_package_name
before merging into document state.
deprecations: HashMap<PackageName, Deprecation>Package-level deprecation findings (issue #205), keyed by raw package name
(same raw/normalized split as yanked_versions above). Derived from the
resolved/“latest” pick in the fetch loop below, not by scanning the full
versions list — see that loop’s comments for why.
fetch_failed: HashMap<PackageName, FetchFailure>Packages whose registry fetch errored or timed out, keyed by raw
package name (same raw/normalized split as yanked_versions above).
Lets diagnostic generation (#267) distinguish “the registry said this
package doesn’t exist” from “the registry couldn’t be asked” instead
of conflating both into a misleading “Unknown package” diagnostic.
no_comparable_versions: HashSet<PackageName>Packages whose registry fetch succeeded but produced zero comparable versions
(#550), keyed by raw package name (same raw/normalized split as
yanked_versions above). Distinct from fetch_failed: the registry was
successfully asked and the package demonstrably exists — it just has nothing a
version-comparison rule can use — so generate_diagnostics_from_cache must
report neither “Registry lookup failed” nor “Unknown package” for it.
failure_summary: Option<FailureSummary>Toast-ready summary of this round’s failures, or None when every package either
resolved or fetched cleanly with no comparable versions. Replaces the previously
independent failed_count/first_error field pair (#480, #490): both bugs were
hand-kept invariants (failed_count > 0 implies first_error.is_some()) rather
than type-enforced ones. failure_summary’s count still counts both a genuine
fetch failure (recorded in fetch_failed above) and a not-found lookup (the
registry answered “no such package”, never recorded in fetch_failed, see #267
C1) — only the fetch_failed subset produces an inline “Registry lookup failed”
diagnostic, so this count can still exceed fetch_failed.len() (#276 S2).
licenses: HashMap<PackageName, Vec<String>>SPDX license identifier(s) for the resolved/“latest” pick, for every package
whose Version::license on the already-fetched version-list entry is
non-empty (issue #660/#661 tier-1 backfill) — today, only the native-list
ecosystems (PyPI, Composer) ever populate this; every other ecosystem’s
Version::license default is empty, so this map stays empty for them.
Deliberately not threaded into PackageVersions itself (that type is
constructed identically across ~40 call sites throughout the workspace,
including files outside this crate’s ownership for this change) —
merge_registry_fetch_result merges this map directly into
deps-lsp’s DocumentState::signals.licenses instead, the same map the tier-3
background pre-fetch (run_license_prefetch) already populates for
Dart/Swift/Gradle/Deno. A merge (not replace), since the two sources are
always disjoint per document (one ecosystem per document) but run as
independent, non-ordered background tasks.
Implementations§
Source§impl FetchResult
impl FetchResult
Sourcepub fn new(
versions: HashMap<PackageName, PackageVersions>,
yanked_versions: HashMap<PackageName, (ConcreteVersion, RemovalStatus)>,
deprecations: HashMap<PackageName, Deprecation>,
fetch_failed: HashMap<PackageName, FetchFailure>,
no_comparable_versions: HashSet<PackageName>,
failure_summary: Option<FailureSummary>,
licenses: HashMap<PackageName, Vec<String>>,
) -> Self
pub fn new( versions: HashMap<PackageName, PackageVersions>, yanked_versions: HashMap<PackageName, (ConcreteVersion, RemovalStatus)>, deprecations: HashMap<PackageName, Deprecation>, fetch_failed: HashMap<PackageName, FetchFailure>, no_comparable_versions: HashSet<PackageName>, failure_summary: Option<FailureSummary>, licenses: HashMap<PackageName, Vec<String>>, ) -> Self
Constructs a FetchResult from its already-computed fields.
#[non_exhaustive] blocks cross-crate struct-literal construction even with every
field named, so a caller outside deps-engine (e.g. a deps-lsp unit test building a
synthetic fetch outcome) needs this constructor instead.
§Examples
use deps_engine::classify::fetch::FetchResult;
use std::collections::{HashMap, HashSet};
let result = FetchResult::new(
HashMap::new(),
HashMap::new(),
HashMap::new(),
HashMap::new(),
HashSet::new(),
None,
HashMap::new(),
);
assert_eq!(result.failed_count(), 0);Parameters, in declaration order (see each field’s own doc above for the full
rationale — this is a quick cross-check against accidental transposition, several
share the same HashMap<PackageName, _>/HashSet<PackageName> shape):
versions (successful fetches), yanked_versions (yank findings),
deprecations (package-level deprecation findings), fetch_failed (errored/timed-out
packages), no_comparable_versions (fetched clean but nothing to compare),
failure_summary, licenses.
Sourcepub fn failed_count(&self) -> usize
pub fn failed_count(&self) -> usize
Total packages whose fetch did not succeed this round (mirrors the old
failed_count field). Requires self not yet partially moved out of — a caller
that has already moved another field (e.g. versions) out of a owned FetchResult
should read failure_summary directly instead, since a partial move blocks any
further whole-self method call.
Sourcepub fn failure_message(&self) -> Option<&str>
pub fn failure_message(&self) -> Option<&str>
The first actionable failure message for this round (mirrors the old first_error
field). Same partial-move caveat as Self::failed_count.